blob: 6261d2fe50fb36823190c567273326e0b2f7fee5 [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
Christian Heimes36281872007-11-30 21:11:28 +0000194/*#ifdef HAVE_FCHMOD
195extern int fchmod(int, mode_t);
196#endif*/
197/*#ifdef HAVE_LCHMOD
198extern int lchmod(const char *, mode_t);
199#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int chown(const char *, uid_t, gid_t);
201extern char *getcwd(char *, int);
202extern char *strerror(int);
203extern int link(const char *, const char *);
204extern int rename(const char *, const char *);
205extern int stat(const char *, struct stat *);
206extern int unlink(const char *);
207extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000209extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000210#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000213#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000215
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000216#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218#ifdef HAVE_UTIME_H
219#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000220#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000222#ifdef HAVE_SYS_UTIME_H
223#include <sys/utime.h>
224#define HAVE_UTIME_H /* pretend we do for the rest of this file */
225#endif /* HAVE_SYS_UTIME_H */
226
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#ifdef HAVE_SYS_TIMES_H
228#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230
231#ifdef HAVE_SYS_PARAM_H
232#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000233#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234
235#ifdef HAVE_SYS_UTSNAME_H
236#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000237#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000239#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000240#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000241#define NAMLEN(dirent) strlen((dirent)->d_name)
242#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000243#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000244#include <direct.h>
245#define NAMLEN(dirent) strlen((dirent)->d_name)
246#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000248#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000249#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000250#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000252#endif
253#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000255#endif
256#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000258#endif
259#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000261#ifdef _MSC_VER
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000262#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <direct.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000264#endif
265#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266#include <io.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000267#endif
268#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269#include <process.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000270#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000271#include "osdefs.h"
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000272#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000274#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000275#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000276#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000277#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278
Guido van Rossumd48f2521997-12-05 22:19:34 +0000279#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000281#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282
Tim Petersbc2e10e2002-03-03 23:17:02 +0000283#ifndef MAXPATHLEN
Thomas Wouters1ddba602006-04-25 15:29:46 +0000284#if defined(PATH_MAX) && PATH_MAX > 1024
285#define MAXPATHLEN PATH_MAX
286#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000287#define MAXPATHLEN 1024
Thomas Wouters1ddba602006-04-25 15:29:46 +0000288#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000289#endif /* MAXPATHLEN */
290
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000291#ifdef UNION_WAIT
292/* Emulate some macros on systems that have a union instead of macros */
293
294#ifndef WIFEXITED
295#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
296#endif
297
298#ifndef WEXITSTATUS
299#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
300#endif
301
302#ifndef WTERMSIG
303#define WTERMSIG(u_wait) ((u_wait).w_termsig)
304#endif
305
Neal Norwitzd5a37542006-03-20 06:48:34 +0000306#define WAIT_TYPE union wait
307#define WAIT_STATUS_INT(s) (s.w_status)
308
309#else /* !UNION_WAIT */
310#define WAIT_TYPE int
311#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000312#endif /* UNION_WAIT */
313
Greg Wardb48bc172000-03-01 21:51:56 +0000314/* Don't use the "_r" form if we don't need it (also, won't have a
315 prototype for it, at least on Solaris -- maybe others as well?). */
316#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
317#define USE_CTERMID_R
318#endif
319
320#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
321#define USE_TMPNAM_R
322#endif
323
Fred Drake699f3522000-06-29 21:12:41 +0000324/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000325#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000326#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000327# define STAT win32_stat
328# define FSTAT win32_fstat
329# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000330#else
331# define STAT stat
332# define FSTAT fstat
333# define STRUCT_STAT struct stat
334#endif
335
Tim Peters11b23062003-04-23 02:39:17 +0000336#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000337#include <sys/mkdev.h>
338#else
339#if defined(MAJOR_IN_SYSMACROS)
340#include <sys/sysmacros.h>
341#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000342#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
343#include <sys/mkdev.h>
344#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000345#endif
Fred Drake699f3522000-06-29 21:12:41 +0000346
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000347#if defined _MSC_VER && _MSC_VER >= 1400
348/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
349 * valid and throw an assertion if it isn't.
350 * Normally, an invalid fd is likely to be a C program error and therefore
351 * an assertion can be useful, but it does contradict the POSIX standard
352 * which for write(2) states:
353 * "Otherwise, -1 shall be returned and errno set to indicate the error."
354 * "[EBADF] The fildes argument is not a valid file descriptor open for
355 * writing."
356 * Furthermore, python allows the user to enter any old integer
357 * as a fd and should merely raise a python exception on error.
358 * The Microsoft CRT doesn't provide an official way to check for the
359 * validity of a file descriptor, but we can emulate its internal behaviour
360 * by using the exported __pinfo data member and knowledge of the
361 * internal structures involved.
362 * The structures below must be updated for each version of visual studio
363 * according to the file internal.h in the CRT source, until MS comes
364 * up with a less hacky way to do this.
365 * (all of this is to avoid globally modifying the CRT behaviour using
366 * _set_invalid_parameter_handler() and _CrtSetReportMode())
367 */
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000368/* The actual size of the structure is determined at runtime.
369 * Only the first items must be present.
370 */
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000371typedef struct {
372 intptr_t osfhnd;
373 char osfile;
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000374} my_ioinfo;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000375
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000376extern __declspec(dllimport) char * __pioinfo[];
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000377#define IOINFO_L2E 5
378#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
379#define IOINFO_ARRAYS 64
380#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
381#define FOPEN 0x01
382#define _NO_CONSOLE_FILENO (intptr_t)-2
383
384/* This function emulates what the windows CRT does to validate file handles */
385int
386_PyVerify_fd(int fd)
387{
388 const int i1 = fd >> IOINFO_L2E;
389 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000390
391 static int sizeof_ioinfo = 0;
392
393 /* Determine the actual size of the ioinfo structure,
394 * as used by the CRT loaded in memory
395 */
396 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
397 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
398 }
399 if (sizeof_ioinfo == 0) {
400 /* This should not happen... */
401 goto fail;
402 }
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000403
404 /* See that it isn't a special CLEAR fileno */
405 if (fd != _NO_CONSOLE_FILENO) {
406 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
407 * we check pointer validity and other info
408 */
409 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
410 /* finally, check that the file is open */
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000411 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
412 if (info->osfile & FOPEN) {
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000413 return 1;
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000414 }
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000415 }
416 }
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000417 fail:
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000418 errno = EBADF;
419 return 0;
420}
421
422/* the special case of checking dup2. The target fd must be in a sensible range */
423static int
424_PyVerify_fd_dup2(int fd1, int fd2)
425{
426 if (!_PyVerify_fd(fd1))
427 return 0;
428 if (fd2 == _NO_CONSOLE_FILENO)
429 return 0;
430 if ((unsigned)fd2 < _NHANDLE_)
431 return 1;
432 else
433 return 0;
434}
435#else
436/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
437#define _PyVerify_fd_dup2(A, B) (1)
438#endif
439
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000440/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000441#ifdef WITH_NEXT_FRAMEWORK
442/* On Darwin/MacOSX a shared library or framework has no access to
443** environ directly, we must obtain it with _NSGetEnviron().
444*/
445#include <crt_externs.h>
446static char **environ;
447#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000448extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000449#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000450
Barry Warsaw53699e91996-12-10 23:23:01 +0000451static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000452convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453{
Barry Warsaw53699e91996-12-10 23:23:01 +0000454 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000455 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000456 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000457 if (d == NULL)
458 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000459#ifdef WITH_NEXT_FRAMEWORK
460 if (environ == NULL)
461 environ = *_NSGetEnviron();
462#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000463 if (environ == NULL)
464 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000465 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000466 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000467 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000468 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000469 char *p = strchr(*e, '=');
470 if (p == NULL)
471 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000472 k = PyString_FromStringAndSize(*e, (int)(p-*e));
Guido van Rossum6a619f41999-08-03 19:41:10 +0000473 if (k == NULL) {
474 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000475 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000476 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000477 v = PyString_FromString(p+1);
Guido van Rossum6a619f41999-08-03 19:41:10 +0000478 if (v == NULL) {
479 PyErr_Clear();
480 Py_DECREF(k);
481 continue;
482 }
483 if (PyDict_GetItem(d, k) == NULL) {
484 if (PyDict_SetItem(d, k, v) != 0)
485 PyErr_Clear();
486 }
487 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000488 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000489 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000490#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000491 {
492 APIRET rc;
493 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
494
495 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000496 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000497 PyObject *v = PyString_FromString(buffer);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000498 PyDict_SetItemString(d, "BEGINLIBPATH", v);
499 Py_DECREF(v);
500 }
501 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
502 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000503 PyObject *v = PyString_FromString(buffer);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000504 PyDict_SetItemString(d, "ENDLIBPATH", v);
505 Py_DECREF(v);
506 }
507 }
508#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000509 return d;
510}
511
512
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000513/* Set a POSIX-specific error from errno, and return NULL */
514
Barry Warsawd58d7641998-07-23 16:14:40 +0000515static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000516posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000517{
Barry Warsawca74da41999-02-09 19:31:45 +0000518 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000519}
Barry Warsawd58d7641998-07-23 16:14:40 +0000520static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000521posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000522{
Barry Warsawca74da41999-02-09 19:31:45 +0000523 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000524}
525
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000526#ifdef Py_WIN_WIDE_FILENAMES
527static PyObject *
528posix_error_with_unicode_filename(Py_UNICODE* name)
529{
530 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
531}
532#endif /* Py_WIN_WIDE_FILENAMES */
533
534
Mark Hammondef8b6542001-05-13 08:04:26 +0000535static PyObject *
536posix_error_with_allocated_filename(char* name)
537{
538 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
539 PyMem_Free(name);
540 return rc;
541}
542
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000543#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000544static PyObject *
545win32_error(char* function, char* filename)
546{
Mark Hammond33a6da92000-08-15 00:46:38 +0000547 /* XXX We should pass the function name along in the future.
548 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000549 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000550 Windows error object, which is non-trivial.
551 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000552 errno = GetLastError();
553 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000554 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000555 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000556 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000557}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000558
559#ifdef Py_WIN_WIDE_FILENAMES
560static PyObject *
561win32_error_unicode(char* function, Py_UNICODE* filename)
562{
563 /* XXX - see win32_error for comments on 'function' */
564 errno = GetLastError();
565 if (filename)
566 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
567 else
568 return PyErr_SetFromWindowsErr(errno);
569}
570
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000571static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000572convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000573{
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000574 if (PyUnicode_CheckExact(*param))
575 Py_INCREF(*param);
576 else if (PyUnicode_Check(*param))
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000577 /* For a Unicode subtype that's not a Unicode object,
578 return a true Unicode object with the same data. */
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000579 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
580 PyUnicode_GET_SIZE(*param));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000581 else
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000582 *param = PyUnicode_FromEncodedObject(*param,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000583 Py_FileSystemDefaultEncoding,
584 "strict");
585 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000586}
587
588#endif /* Py_WIN_WIDE_FILENAMES */
589
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000590#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000591
Guido van Rossumd48f2521997-12-05 22:19:34 +0000592#if defined(PYOS_OS2)
593/**********************************************************************
594 * Helper Function to Trim and Format OS/2 Messages
595 **********************************************************************/
596 static void
597os2_formatmsg(char *msgbuf, int msglen, char *reason)
598{
599 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
600
601 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
602 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
603
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000604 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000605 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
606 }
607
608 /* Add Optional Reason Text */
609 if (reason) {
610 strcat(msgbuf, " : ");
611 strcat(msgbuf, reason);
612 }
613}
614
615/**********************************************************************
616 * Decode an OS/2 Operating System Error Code
617 *
618 * A convenience function to lookup an OS/2 error code and return a
619 * text message we can use to raise a Python exception.
620 *
621 * Notes:
622 * The messages for errors returned from the OS/2 kernel reside in
623 * the file OSO001.MSG in the \OS2 directory hierarchy.
624 *
625 **********************************************************************/
626 static char *
627os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
628{
629 APIRET rc;
630 ULONG msglen;
631
632 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
633 Py_BEGIN_ALLOW_THREADS
634 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
635 errorcode, "oso001.msg", &msglen);
636 Py_END_ALLOW_THREADS
637
638 if (rc == NO_ERROR)
639 os2_formatmsg(msgbuf, msglen, reason);
640 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000641 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000642 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000643
644 return msgbuf;
645}
646
647/* Set an OS/2-specific error and return NULL. OS/2 kernel
648 errors are not in a global variable e.g. 'errno' nor are
649 they congruent with posix error numbers. */
650
651static PyObject * os2_error(int code)
652{
653 char text[1024];
654 PyObject *v;
655
656 os2_strerror(text, sizeof(text), code, "");
657
658 v = Py_BuildValue("(is)", code, text);
659 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000660 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000661 Py_DECREF(v);
662 }
663 return NULL; /* Signal to Python that an Exception is Pending */
664}
665
666#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000667
668/* POSIX generic methods */
669
Barry Warsaw53699e91996-12-10 23:23:01 +0000670static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000671posix_fildes(PyObject *fdobj, int (*func)(int))
672{
673 int fd;
674 int res;
675 fd = PyObject_AsFileDescriptor(fdobj);
676 if (fd < 0)
677 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000678 if (!_PyVerify_fd(fd))
679 return posix_error();
Fred Drake4d1e64b2002-04-15 19:40:07 +0000680 Py_BEGIN_ALLOW_THREADS
681 res = (*func)(fd);
682 Py_END_ALLOW_THREADS
683 if (res < 0)
684 return posix_error();
685 Py_INCREF(Py_None);
686 return Py_None;
687}
Guido van Rossum21142a01999-01-08 21:05:37 +0000688
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000689#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000690static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000691unicode_file_names(void)
692{
693 static int canusewide = -1;
694 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000695 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000696 the Windows NT family. */
697 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
698 }
699 return canusewide;
700}
701#endif
Tim Peters11b23062003-04-23 02:39:17 +0000702
Guido van Rossum21142a01999-01-08 21:05:37 +0000703static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000704posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000705{
Mark Hammondef8b6542001-05-13 08:04:26 +0000706 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000707 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000708 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000709 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000710 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000711 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000712 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000713 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000714 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000715 return posix_error_with_allocated_filename(path1);
716 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000717 Py_INCREF(Py_None);
718 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000719}
720
Barry Warsaw53699e91996-12-10 23:23:01 +0000721static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000722posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000723 char *format,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000724 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000725{
Mark Hammondef8b6542001-05-13 08:04:26 +0000726 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000727 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000728 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000729 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000730 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000731 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000732 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000733 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000734 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000735 PyMem_Free(path1);
736 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000737 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000738 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000739 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000740 Py_INCREF(Py_None);
741 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000742}
743
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000744#ifdef Py_WIN_WIDE_FILENAMES
745static PyObject*
746win32_1str(PyObject* args, char* func,
747 char* format, BOOL (__stdcall *funcA)(LPCSTR),
748 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
749{
750 PyObject *uni;
751 char *ansi;
752 BOOL result;
753 if (unicode_file_names()) {
754 if (!PyArg_ParseTuple(args, wformat, &uni))
755 PyErr_Clear();
756 else {
757 Py_BEGIN_ALLOW_THREADS
758 result = funcW(PyUnicode_AsUnicode(uni));
759 Py_END_ALLOW_THREADS
760 if (!result)
761 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
762 Py_INCREF(Py_None);
763 return Py_None;
764 }
765 }
766 if (!PyArg_ParseTuple(args, format, &ansi))
767 return NULL;
768 Py_BEGIN_ALLOW_THREADS
769 result = funcA(ansi);
770 Py_END_ALLOW_THREADS
771 if (!result)
772 return win32_error(func, ansi);
773 Py_INCREF(Py_None);
774 return Py_None;
775
776}
777
778/* This is a reimplementation of the C library's chdir function,
779 but one that produces Win32 errors instead of DOS error codes.
780 chdir is essentially a wrapper around SetCurrentDirectory; however,
781 it also needs to set "magic" environment variables indicating
782 the per-drive current directory, which are of the form =<drive>: */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000783static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000784win32_chdir(LPCSTR path)
785{
786 char new_path[MAX_PATH+1];
787 int result;
788 char env[4] = "=x:";
789
790 if(!SetCurrentDirectoryA(path))
791 return FALSE;
792 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
793 if (!result)
794 return FALSE;
795 /* In the ANSI API, there should not be any paths longer
796 than MAX_PATH. */
797 assert(result <= MAX_PATH+1);
798 if (strncmp(new_path, "\\\\", 2) == 0 ||
799 strncmp(new_path, "//", 2) == 0)
800 /* UNC path, nothing to do. */
801 return TRUE;
802 env[1] = new_path[0];
803 return SetEnvironmentVariableA(env, new_path);
804}
805
806/* The Unicode version differs from the ANSI version
807 since the current directory might exceed MAX_PATH characters */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000808static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000809win32_wchdir(LPCWSTR path)
810{
811 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
812 int result;
813 wchar_t env[4] = L"=x:";
814
815 if(!SetCurrentDirectoryW(path))
816 return FALSE;
817 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
818 if (!result)
819 return FALSE;
820 if (result > MAX_PATH+1) {
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000821 new_path = malloc(result * sizeof(wchar_t));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000822 if (!new_path) {
823 SetLastError(ERROR_OUTOFMEMORY);
824 return FALSE;
825 }
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000826 result = GetCurrentDirectoryW(result, new_path);
Hirokazu Yamamoto6c75a302008-10-09 10:11:21 +0000827 if (!result) {
828 free(new_path);
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000829 return FALSE;
Hirokazu Yamamoto6c75a302008-10-09 10:11:21 +0000830 }
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000831 }
832 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
833 wcsncmp(new_path, L"//", 2) == 0)
834 /* UNC path, nothing to do. */
835 return TRUE;
836 env[1] = new_path[0];
837 result = SetEnvironmentVariableW(env, new_path);
838 if (new_path != _new_path)
839 free(new_path);
840 return result;
841}
842#endif
843
Martin v. Löwis14694662006-02-03 12:54:16 +0000844#ifdef MS_WINDOWS
845/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
846 - time stamps are restricted to second resolution
847 - file modification times suffer from forth-and-back conversions between
848 UTC and local time
849 Therefore, we implement our own stat, based on the Win32 API directly.
850*/
851#define HAVE_STAT_NSEC 1
852
853struct win32_stat{
854 int st_dev;
855 __int64 st_ino;
856 unsigned short st_mode;
857 int st_nlink;
858 int st_uid;
859 int st_gid;
860 int st_rdev;
861 __int64 st_size;
862 int st_atime;
863 int st_atime_nsec;
864 int st_mtime;
865 int st_mtime_nsec;
866 int st_ctime;
867 int st_ctime_nsec;
868};
869
870static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
871
872static void
873FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
874{
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000875 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
876 /* Cannot simply cast and dereference in_ptr,
877 since it might not be aligned properly */
878 __int64 in;
879 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000880 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
881 /* XXX Win32 supports time stamps past 2038; we currently don't */
882 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
883}
884
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000885static void
886time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
887{
888 /* XXX endianness */
889 __int64 out;
890 out = time_in + secs_between_epochs;
Martin v. Löwisf43893a2006-10-09 20:44:25 +0000891 out = out * 10000000 + nsec_in / 100;
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000892 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000893}
894
Martin v. Löwis14694662006-02-03 12:54:16 +0000895/* Below, we *know* that ugo+r is 0444 */
896#if _S_IREAD != 0400
897#error Unsupported C library
898#endif
899static int
900attributes_to_mode(DWORD attr)
901{
902 int m = 0;
903 if (attr & FILE_ATTRIBUTE_DIRECTORY)
904 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
905 else
906 m |= _S_IFREG;
907 if (attr & FILE_ATTRIBUTE_READONLY)
908 m |= 0444;
909 else
910 m |= 0666;
911 return m;
912}
913
914static int
915attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
916{
917 memset(result, 0, sizeof(*result));
918 result->st_mode = attributes_to_mode(info->dwFileAttributes);
919 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
920 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
921 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
922 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
923
924 return 0;
925}
926
Martin v. Löwis012bc722006-10-15 09:43:39 +0000927/* Emulate GetFileAttributesEx[AW] on Windows 95 */
928static int checked = 0;
929static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
930static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
931static void
932check_gfax()
933{
934 HINSTANCE hKernel32;
935 if (checked)
936 return;
937 checked = 1;
938 hKernel32 = GetModuleHandle("KERNEL32");
939 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
940 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
941}
942
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000943static BOOL
944attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
945{
946 HANDLE hFindFile;
947 WIN32_FIND_DATAA FileData;
948 hFindFile = FindFirstFileA(pszFile, &FileData);
949 if (hFindFile == INVALID_HANDLE_VALUE)
950 return FALSE;
951 FindClose(hFindFile);
952 pfad->dwFileAttributes = FileData.dwFileAttributes;
953 pfad->ftCreationTime = FileData.ftCreationTime;
954 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
955 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
956 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
957 pfad->nFileSizeLow = FileData.nFileSizeLow;
958 return TRUE;
959}
960
961static BOOL
962attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
963{
964 HANDLE hFindFile;
965 WIN32_FIND_DATAW FileData;
966 hFindFile = FindFirstFileW(pszFile, &FileData);
967 if (hFindFile == INVALID_HANDLE_VALUE)
968 return FALSE;
969 FindClose(hFindFile);
970 pfad->dwFileAttributes = FileData.dwFileAttributes;
971 pfad->ftCreationTime = FileData.ftCreationTime;
972 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
973 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
974 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
975 pfad->nFileSizeLow = FileData.nFileSizeLow;
976 return TRUE;
977}
978
Martin v. Löwis012bc722006-10-15 09:43:39 +0000979static BOOL WINAPI
980Py_GetFileAttributesExA(LPCSTR pszFile,
981 GET_FILEEX_INFO_LEVELS level,
982 LPVOID pv)
983{
984 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000985 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
986 /* First try to use the system's implementation, if that is
987 available and either succeeds to gives an error other than
988 that it isn't implemented. */
989 check_gfax();
990 if (gfaxa) {
991 result = gfaxa(pszFile, level, pv);
992 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
993 return result;
994 }
995 /* It's either not present, or not implemented.
996 Emulate using FindFirstFile. */
997 if (level != GetFileExInfoStandard) {
998 SetLastError(ERROR_INVALID_PARAMETER);
999 return FALSE;
1000 }
1001 /* Use GetFileAttributes to validate that the file name
1002 does not contain wildcards (which FindFirstFile would
1003 accept). */
1004 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
1005 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001006 return attributes_from_dir(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +00001007}
1008
1009static BOOL WINAPI
1010Py_GetFileAttributesExW(LPCWSTR pszFile,
1011 GET_FILEEX_INFO_LEVELS level,
1012 LPVOID pv)
1013{
1014 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +00001015 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1016 /* First try to use the system's implementation, if that is
1017 available and either succeeds to gives an error other than
1018 that it isn't implemented. */
1019 check_gfax();
1020 if (gfaxa) {
1021 result = gfaxw(pszFile, level, pv);
1022 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1023 return result;
1024 }
1025 /* It's either not present, or not implemented.
1026 Emulate using FindFirstFile. */
1027 if (level != GetFileExInfoStandard) {
1028 SetLastError(ERROR_INVALID_PARAMETER);
1029 return FALSE;
1030 }
1031 /* Use GetFileAttributes to validate that the file name
1032 does not contain wildcards (which FindFirstFile would
1033 accept). */
1034 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1035 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001036 return attributes_from_dir_w(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +00001037}
1038
Martin v. Löwis14694662006-02-03 12:54:16 +00001039static int
1040win32_stat(const char* path, struct win32_stat *result)
1041{
1042 WIN32_FILE_ATTRIBUTE_DATA info;
1043 int code;
1044 char *dot;
1045 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +00001046 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001047 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1048 /* Protocol violation: we explicitly clear errno, instead of
1049 setting it to a POSIX error. Callers should use GetLastError. */
1050 errno = 0;
1051 return -1;
1052 } else {
1053 /* Could not get attributes on open file. Fall back to
1054 reading the directory. */
1055 if (!attributes_from_dir(path, &info)) {
1056 /* Very strange. This should not fail now */
1057 errno = 0;
1058 return -1;
1059 }
1060 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001061 }
1062 code = attribute_data_to_stat(&info, result);
1063 if (code != 0)
1064 return code;
1065 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1066 dot = strrchr(path, '.');
1067 if (dot) {
1068 if (stricmp(dot, ".bat") == 0 ||
1069 stricmp(dot, ".cmd") == 0 ||
1070 stricmp(dot, ".exe") == 0 ||
1071 stricmp(dot, ".com") == 0)
1072 result->st_mode |= 0111;
1073 }
1074 return code;
1075}
1076
1077static int
1078win32_wstat(const wchar_t* path, struct win32_stat *result)
1079{
1080 int code;
1081 const wchar_t *dot;
1082 WIN32_FILE_ATTRIBUTE_DATA info;
1083 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +00001084 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001085 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1086 /* Protocol violation: we explicitly clear errno, instead of
1087 setting it to a POSIX error. Callers should use GetLastError. */
1088 errno = 0;
1089 return -1;
1090 } else {
1091 /* Could not get attributes on open file. Fall back to
1092 reading the directory. */
1093 if (!attributes_from_dir_w(path, &info)) {
1094 /* Very strange. This should not fail now */
1095 errno = 0;
1096 return -1;
1097 }
1098 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001099 }
1100 code = attribute_data_to_stat(&info, result);
1101 if (code < 0)
1102 return code;
1103 /* Set IFEXEC if it is an .exe, .bat, ... */
1104 dot = wcsrchr(path, '.');
1105 if (dot) {
1106 if (_wcsicmp(dot, L".bat") == 0 ||
1107 _wcsicmp(dot, L".cmd") == 0 ||
1108 _wcsicmp(dot, L".exe") == 0 ||
1109 _wcsicmp(dot, L".com") == 0)
1110 result->st_mode |= 0111;
1111 }
1112 return code;
1113}
1114
1115static int
1116win32_fstat(int file_number, struct win32_stat *result)
1117{
1118 BY_HANDLE_FILE_INFORMATION info;
1119 HANDLE h;
1120 int type;
1121
1122 h = (HANDLE)_get_osfhandle(file_number);
1123
1124 /* Protocol violation: we explicitly clear errno, instead of
1125 setting it to a POSIX error. Callers should use GetLastError. */
1126 errno = 0;
1127
1128 if (h == INVALID_HANDLE_VALUE) {
1129 /* This is really a C library error (invalid file handle).
1130 We set the Win32 error to the closes one matching. */
1131 SetLastError(ERROR_INVALID_HANDLE);
1132 return -1;
1133 }
1134 memset(result, 0, sizeof(*result));
1135
1136 type = GetFileType(h);
1137 if (type == FILE_TYPE_UNKNOWN) {
1138 DWORD error = GetLastError();
1139 if (error != 0) {
1140 return -1;
1141 }
1142 /* else: valid but unknown file */
1143 }
1144
1145 if (type != FILE_TYPE_DISK) {
1146 if (type == FILE_TYPE_CHAR)
1147 result->st_mode = _S_IFCHR;
1148 else if (type == FILE_TYPE_PIPE)
1149 result->st_mode = _S_IFIFO;
1150 return 0;
1151 }
1152
1153 if (!GetFileInformationByHandle(h, &info)) {
1154 return -1;
1155 }
1156
1157 /* similar to stat() */
1158 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1159 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1160 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1161 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1162 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1163 /* specific to fstat() */
1164 result->st_nlink = info.nNumberOfLinks;
1165 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1166 return 0;
1167}
1168
1169#endif /* MS_WINDOWS */
1170
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001171PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001172"stat_result: Result from stat or lstat.\n\n\
1173This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001174 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001175or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1176\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001177Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1178or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001179\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001180See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001181
1182static PyStructSequence_Field stat_result_fields[] = {
1183 {"st_mode", "protection bits"},
1184 {"st_ino", "inode"},
1185 {"st_dev", "device"},
1186 {"st_nlink", "number of hard links"},
1187 {"st_uid", "user ID of owner"},
1188 {"st_gid", "group ID of owner"},
1189 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001190 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1191 {NULL, "integer time of last access"},
1192 {NULL, "integer time of last modification"},
1193 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001194 {"st_atime", "time of last access"},
1195 {"st_mtime", "time of last modification"},
1196 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001197#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001198 {"st_blksize", "blocksize for filesystem I/O"},
1199#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001200#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001201 {"st_blocks", "number of blocks allocated"},
1202#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001203#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001204 {"st_rdev", "device type (if inode device)"},
1205#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001206#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1207 {"st_flags", "user defined flags for file"},
1208#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001209#ifdef HAVE_STRUCT_STAT_ST_GEN
1210 {"st_gen", "generation number"},
1211#endif
1212#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1213 {"st_birthtime", "time of creation"},
1214#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001215 {0}
1216};
1217
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001218#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001219#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001220#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001221#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001222#endif
1223
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001224#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001225#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1226#else
1227#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1228#endif
1229
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001230#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001231#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1232#else
1233#define ST_RDEV_IDX ST_BLOCKS_IDX
1234#endif
1235
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001236#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1237#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1238#else
1239#define ST_FLAGS_IDX ST_RDEV_IDX
1240#endif
1241
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001242#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001243#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001244#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001245#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001246#endif
1247
1248#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1249#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1250#else
1251#define ST_BIRTHTIME_IDX ST_GEN_IDX
1252#endif
1253
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001254static PyStructSequence_Desc stat_result_desc = {
1255 "stat_result", /* name */
1256 stat_result__doc__, /* doc */
1257 stat_result_fields,
1258 10
1259};
1260
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001261PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001262"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1263This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001264 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001265or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001266\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001267See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001268
1269static PyStructSequence_Field statvfs_result_fields[] = {
1270 {"f_bsize", },
1271 {"f_frsize", },
1272 {"f_blocks", },
1273 {"f_bfree", },
1274 {"f_bavail", },
1275 {"f_files", },
1276 {"f_ffree", },
1277 {"f_favail", },
1278 {"f_flag", },
1279 {"f_namemax",},
1280 {0}
1281};
1282
1283static PyStructSequence_Desc statvfs_result_desc = {
1284 "statvfs_result", /* name */
1285 statvfs_result__doc__, /* doc */
1286 statvfs_result_fields,
1287 10
1288};
1289
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001290static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001291static PyTypeObject StatResultType;
1292static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001293static newfunc structseq_new;
1294
1295static PyObject *
1296statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1297{
1298 PyStructSequence *result;
1299 int i;
1300
1301 result = (PyStructSequence*)structseq_new(type, args, kwds);
1302 if (!result)
1303 return NULL;
1304 /* If we have been initialized from a tuple,
1305 st_?time might be set to None. Initialize it
1306 from the int slots. */
1307 for (i = 7; i <= 9; i++) {
1308 if (result->ob_item[i+3] == Py_None) {
1309 Py_DECREF(Py_None);
1310 Py_INCREF(result->ob_item[i]);
1311 result->ob_item[i+3] = result->ob_item[i];
1312 }
1313 }
1314 return (PyObject*)result;
1315}
1316
1317
1318
1319/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001320static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001321
1322PyDoc_STRVAR(stat_float_times__doc__,
1323"stat_float_times([newval]) -> oldval\n\n\
1324Determine whether os.[lf]stat represents time stamps as float objects.\n\
1325If newval is True, future calls to stat() return floats, if it is False,\n\
1326future calls return ints. \n\
1327If newval is omitted, return the current setting.\n");
1328
1329static PyObject*
1330stat_float_times(PyObject* self, PyObject *args)
1331{
1332 int newval = -1;
1333 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1334 return NULL;
1335 if (newval == -1)
1336 /* Return old value */
1337 return PyBool_FromLong(_stat_float_times);
1338 _stat_float_times = newval;
1339 Py_INCREF(Py_None);
1340 return Py_None;
1341}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001342
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001343static void
1344fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1345{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001346 PyObject *fval,*ival;
1347#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001348 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001349#else
1350 ival = PyInt_FromLong((long)sec);
1351#endif
Neal Norwitze0a81af2006-08-12 01:50:38 +00001352 if (!ival)
1353 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001354 if (_stat_float_times) {
1355 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1356 } else {
1357 fval = ival;
1358 Py_INCREF(fval);
1359 }
1360 PyStructSequence_SET_ITEM(v, index, ival);
1361 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001362}
1363
Tim Peters5aa91602002-01-30 05:46:57 +00001364/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001365 (used by posix_stat() and posix_fstat()) */
1366static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001367_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001368{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001369 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001370 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001371 if (v == NULL)
1372 return NULL;
1373
Martin v. Löwis14694662006-02-03 12:54:16 +00001374 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001375#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001376 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001377 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001378#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001379 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001380#endif
1381#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001382 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001383 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001384#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001385 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001386#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001387 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1388 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1389 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001390#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001391 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001392 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001393#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001394 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001395#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001396
Martin v. Löwis14694662006-02-03 12:54:16 +00001397#if defined(HAVE_STAT_TV_NSEC)
1398 ansec = st->st_atim.tv_nsec;
1399 mnsec = st->st_mtim.tv_nsec;
1400 cnsec = st->st_ctim.tv_nsec;
1401#elif defined(HAVE_STAT_TV_NSEC2)
1402 ansec = st->st_atimespec.tv_nsec;
1403 mnsec = st->st_mtimespec.tv_nsec;
1404 cnsec = st->st_ctimespec.tv_nsec;
1405#elif defined(HAVE_STAT_NSEC)
1406 ansec = st->st_atime_nsec;
1407 mnsec = st->st_mtime_nsec;
1408 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001409#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001410 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001411#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001412 fill_time(v, 7, st->st_atime, ansec);
1413 fill_time(v, 8, st->st_mtime, mnsec);
1414 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001415
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001416#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001417 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001418 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001419#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001420#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001421 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001422 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001423#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001424#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001425 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001426 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001427#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001428#ifdef HAVE_STRUCT_STAT_ST_GEN
1429 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001430 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001431#endif
1432#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1433 {
1434 PyObject *val;
1435 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001436 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001437#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001438 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001439#else
1440 bnsec = 0;
1441#endif
1442 if (_stat_float_times) {
1443 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1444 } else {
1445 val = PyInt_FromLong((long)bsec);
1446 }
1447 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1448 val);
1449 }
1450#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001451#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1452 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001453 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001454#endif
Fred Drake699f3522000-06-29 21:12:41 +00001455
1456 if (PyErr_Occurred()) {
1457 Py_DECREF(v);
1458 return NULL;
1459 }
1460
1461 return v;
1462}
1463
Martin v. Löwisd8948722004-06-02 09:57:56 +00001464#ifdef MS_WINDOWS
1465
1466/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1467 where / can be used in place of \ and the trailing slash is optional.
1468 Both SERVER and SHARE must have at least one character.
1469*/
1470
1471#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1472#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001473#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001474#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001475#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001476
Tim Peters4ad82172004-08-30 17:02:04 +00001477static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001478IsUNCRootA(char *path, int pathlen)
1479{
1480 #define ISSLASH ISSLASHA
1481
1482 int i, share;
1483
1484 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1485 /* minimum UNCRoot is \\x\y */
1486 return FALSE;
1487 for (i = 2; i < pathlen ; i++)
1488 if (ISSLASH(path[i])) break;
1489 if (i == 2 || i == pathlen)
1490 /* do not allow \\\SHARE or \\SERVER */
1491 return FALSE;
1492 share = i+1;
1493 for (i = share; i < pathlen; i++)
1494 if (ISSLASH(path[i])) break;
1495 return (i != share && (i == pathlen || i == pathlen-1));
1496
1497 #undef ISSLASH
1498}
1499
1500#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001501static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001502IsUNCRootW(Py_UNICODE *path, int pathlen)
1503{
1504 #define ISSLASH ISSLASHW
1505
1506 int i, share;
1507
1508 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1509 /* minimum UNCRoot is \\x\y */
1510 return FALSE;
1511 for (i = 2; i < pathlen ; i++)
1512 if (ISSLASH(path[i])) break;
1513 if (i == 2 || i == pathlen)
1514 /* do not allow \\\SHARE or \\SERVER */
1515 return FALSE;
1516 share = i+1;
1517 for (i = share; i < pathlen; i++)
1518 if (ISSLASH(path[i])) break;
1519 return (i != share && (i == pathlen || i == pathlen-1));
1520
1521 #undef ISSLASH
1522}
1523#endif /* Py_WIN_WIDE_FILENAMES */
1524#endif /* MS_WINDOWS */
1525
Barry Warsaw53699e91996-12-10 23:23:01 +00001526static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001527posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001528 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001529#ifdef __VMS
1530 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1531#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001532 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001533#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001534 char *wformat,
1535 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001536{
Fred Drake699f3522000-06-29 21:12:41 +00001537 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001538 char *path = NULL; /* pass this to stat; do not free() it */
1539 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001540 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001541 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001542
1543#ifdef Py_WIN_WIDE_FILENAMES
1544 /* If on wide-character-capable OS see if argument
1545 is Unicode and if so use wide API. */
1546 if (unicode_file_names()) {
1547 PyUnicodeObject *po;
1548 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001549 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1550
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001551 Py_BEGIN_ALLOW_THREADS
1552 /* PyUnicode_AS_UNICODE result OK without
1553 thread lock as it is a simple dereference. */
1554 res = wstatfunc(wpath, &st);
1555 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001556
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001557 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001558 return win32_error_unicode("stat", wpath);
1559 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001560 }
1561 /* Drop the argument parsing error as narrow strings
1562 are also valid. */
1563 PyErr_Clear();
1564 }
1565#endif
1566
Tim Peters5aa91602002-01-30 05:46:57 +00001567 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001568 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001569 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001570 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001571
Barry Warsaw53699e91996-12-10 23:23:01 +00001572 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001573 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001574 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001575
1576 if (res != 0) {
1577#ifdef MS_WINDOWS
1578 result = win32_error("stat", pathfree);
1579#else
1580 result = posix_error_with_filename(pathfree);
1581#endif
1582 }
1583 else
1584 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001585
Tim Peters500bd032001-12-19 19:05:01 +00001586 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001587 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001588}
1589
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001590/* POSIX methods */
1591
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001592PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001593"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001594Use the real uid/gid to test for access to a path. Note that most\n\
1595operations will use the effective uid/gid, therefore this routine can\n\
1596be used in a suid/sgid environment to test if the invoking user has the\n\
1597specified access to the path. The mode argument can be F_OK to test\n\
1598existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001599
1600static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001601posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001602{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001603 char *path;
1604 int mode;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001605
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001606#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001607 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001608 if (unicode_file_names()) {
1609 PyUnicodeObject *po;
1610 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1611 Py_BEGIN_ALLOW_THREADS
1612 /* PyUnicode_AS_UNICODE OK without thread lock as
1613 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001614 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001615 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001616 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001617 }
1618 /* Drop the argument parsing error as narrow strings
1619 are also valid. */
1620 PyErr_Clear();
1621 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001622 if (!PyArg_ParseTuple(args, "eti:access",
1623 Py_FileSystemDefaultEncoding, &path, &mode))
1624 return 0;
1625 Py_BEGIN_ALLOW_THREADS
1626 attr = GetFileAttributesA(path);
1627 Py_END_ALLOW_THREADS
1628 PyMem_Free(path);
1629finish:
1630 if (attr == 0xFFFFFFFF)
1631 /* File does not exist, or cannot read attributes */
1632 return PyBool_FromLong(0);
1633 /* Access is possible if either write access wasn't requested, or
Martin v. Löwis7b3cc062007-12-03 23:09:04 +00001634 the file isn't read-only, or if it's a directory, as there are
1635 no read-only directories on Windows. */
1636 return PyBool_FromLong(!(mode & 2)
1637 || !(attr & FILE_ATTRIBUTE_READONLY)
1638 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001639#else
1640 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001641 if (!PyArg_ParseTuple(args, "eti:access",
1642 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001643 return NULL;
1644 Py_BEGIN_ALLOW_THREADS
1645 res = access(path, mode);
1646 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001647 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001648 return PyBool_FromLong(res == 0);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001649#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001650}
1651
Guido van Rossumd371ff11999-01-25 16:12:23 +00001652#ifndef F_OK
1653#define F_OK 0
1654#endif
1655#ifndef R_OK
1656#define R_OK 4
1657#endif
1658#ifndef W_OK
1659#define W_OK 2
1660#endif
1661#ifndef X_OK
1662#define X_OK 1
1663#endif
1664
1665#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001666PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001667"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001668Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001669
1670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001671posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001672{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001673 int id;
1674 char *ret;
1675
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001676 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001677 return NULL;
1678
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001679#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001680 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001681 if (id == 0) {
1682 ret = ttyname();
1683 }
1684 else {
1685 ret = NULL;
1686 }
1687#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001688 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001689#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001690 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001691 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001692 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001693}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001694#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001695
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001696#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001697PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001698"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001699Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001700
1701static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001702posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001703{
1704 char *ret;
1705 char buffer[L_ctermid];
1706
Greg Wardb48bc172000-03-01 21:51:56 +00001707#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001708 ret = ctermid_r(buffer);
1709#else
1710 ret = ctermid(buffer);
1711#endif
1712 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001713 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001714 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001715}
1716#endif
1717
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001718PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001719"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001720Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001721
Barry Warsaw53699e91996-12-10 23:23:01 +00001722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001723posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001724{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001725#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001726 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001727#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001728 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001729#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001730 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001731#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001732 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001733#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001734}
1735
Fred Drake4d1e64b2002-04-15 19:40:07 +00001736#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001737PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001738"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001739Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001740opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001741
1742static PyObject *
1743posix_fchdir(PyObject *self, PyObject *fdobj)
1744{
1745 return posix_fildes(fdobj, fchdir);
1746}
1747#endif /* HAVE_FCHDIR */
1748
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001749
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001750PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001751"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001752Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001753
Barry Warsaw53699e91996-12-10 23:23:01 +00001754static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001755posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001756{
Mark Hammondef8b6542001-05-13 08:04:26 +00001757 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001758 int i;
1759 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001760#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001761 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001762 if (unicode_file_names()) {
1763 PyUnicodeObject *po;
1764 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1765 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001766 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1767 if (attr != 0xFFFFFFFF) {
1768 if (i & _S_IWRITE)
1769 attr &= ~FILE_ATTRIBUTE_READONLY;
1770 else
1771 attr |= FILE_ATTRIBUTE_READONLY;
1772 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1773 }
1774 else
1775 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001776 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001777 if (!res)
1778 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001779 PyUnicode_AS_UNICODE(po));
1780 Py_INCREF(Py_None);
1781 return Py_None;
1782 }
1783 /* Drop the argument parsing error as narrow strings
1784 are also valid. */
1785 PyErr_Clear();
1786 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001787 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1788 &path, &i))
1789 return NULL;
1790 Py_BEGIN_ALLOW_THREADS
1791 attr = GetFileAttributesA(path);
1792 if (attr != 0xFFFFFFFF) {
1793 if (i & _S_IWRITE)
1794 attr &= ~FILE_ATTRIBUTE_READONLY;
1795 else
1796 attr |= FILE_ATTRIBUTE_READONLY;
1797 res = SetFileAttributesA(path, attr);
1798 }
1799 else
1800 res = 0;
1801 Py_END_ALLOW_THREADS
1802 if (!res) {
1803 win32_error("chmod", path);
1804 PyMem_Free(path);
1805 return NULL;
1806 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001807 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001808 Py_INCREF(Py_None);
1809 return Py_None;
1810#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001811 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001812 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001813 return NULL;
1814 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001815 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001816 Py_END_ALLOW_THREADS
1817 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001818 return posix_error_with_allocated_filename(path);
1819 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001820 Py_INCREF(Py_None);
1821 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001822#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001823}
1824
Christian Heimes36281872007-11-30 21:11:28 +00001825#ifdef HAVE_FCHMOD
1826PyDoc_STRVAR(posix_fchmod__doc__,
1827"fchmod(fd, mode)\n\n\
1828Change the access permissions of the file given by file\n\
1829descriptor fd.");
1830
1831static PyObject *
1832posix_fchmod(PyObject *self, PyObject *args)
1833{
1834 int fd, mode, res;
1835 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1836 return NULL;
1837 Py_BEGIN_ALLOW_THREADS
1838 res = fchmod(fd, mode);
1839 Py_END_ALLOW_THREADS
1840 if (res < 0)
1841 return posix_error();
1842 Py_RETURN_NONE;
1843}
1844#endif /* HAVE_FCHMOD */
1845
1846#ifdef HAVE_LCHMOD
1847PyDoc_STRVAR(posix_lchmod__doc__,
1848"lchmod(path, mode)\n\n\
1849Change the access permissions of a file. If path is a symlink, this\n\
1850affects the link itself rather than the target.");
1851
1852static PyObject *
1853posix_lchmod(PyObject *self, PyObject *args)
1854{
1855 char *path = NULL;
1856 int i;
1857 int res;
1858 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1859 &path, &i))
1860 return NULL;
1861 Py_BEGIN_ALLOW_THREADS
1862 res = lchmod(path, i);
1863 Py_END_ALLOW_THREADS
1864 if (res < 0)
1865 return posix_error_with_allocated_filename(path);
1866 PyMem_Free(path);
1867 Py_RETURN_NONE;
1868}
1869#endif /* HAVE_LCHMOD */
1870
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001871
Martin v. Löwis382abef2007-02-19 10:55:19 +00001872#ifdef HAVE_CHFLAGS
1873PyDoc_STRVAR(posix_chflags__doc__,
1874"chflags(path, flags)\n\n\
1875Set file flags.");
1876
1877static PyObject *
1878posix_chflags(PyObject *self, PyObject *args)
1879{
1880 char *path;
1881 unsigned long flags;
1882 int res;
1883 if (!PyArg_ParseTuple(args, "etk:chflags",
1884 Py_FileSystemDefaultEncoding, &path, &flags))
1885 return NULL;
1886 Py_BEGIN_ALLOW_THREADS
1887 res = chflags(path, flags);
1888 Py_END_ALLOW_THREADS
1889 if (res < 0)
1890 return posix_error_with_allocated_filename(path);
1891 PyMem_Free(path);
1892 Py_INCREF(Py_None);
1893 return Py_None;
1894}
1895#endif /* HAVE_CHFLAGS */
1896
1897#ifdef HAVE_LCHFLAGS
1898PyDoc_STRVAR(posix_lchflags__doc__,
1899"lchflags(path, flags)\n\n\
1900Set file flags.\n\
1901This function will not follow symbolic links.");
1902
1903static PyObject *
1904posix_lchflags(PyObject *self, PyObject *args)
1905{
1906 char *path;
1907 unsigned long flags;
1908 int res;
1909 if (!PyArg_ParseTuple(args, "etk:lchflags",
1910 Py_FileSystemDefaultEncoding, &path, &flags))
1911 return NULL;
1912 Py_BEGIN_ALLOW_THREADS
1913 res = lchflags(path, flags);
1914 Py_END_ALLOW_THREADS
1915 if (res < 0)
1916 return posix_error_with_allocated_filename(path);
1917 PyMem_Free(path);
1918 Py_INCREF(Py_None);
1919 return Py_None;
1920}
1921#endif /* HAVE_LCHFLAGS */
1922
Martin v. Löwis244edc82001-10-04 22:44:26 +00001923#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001924PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001925"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001926Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001927
1928static PyObject *
1929posix_chroot(PyObject *self, PyObject *args)
1930{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001931 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001932}
1933#endif
1934
Guido van Rossum21142a01999-01-08 21:05:37 +00001935#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001936PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001937"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001938force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001939
1940static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001941posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001942{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001943 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001944}
1945#endif /* HAVE_FSYNC */
1946
1947#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001948
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001949#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001950extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1951#endif
1952
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001953PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001954"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001955force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001956 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001957
1958static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001959posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001960{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001961 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001962}
1963#endif /* HAVE_FDATASYNC */
1964
1965
Fredrik Lundh10723342000-07-10 16:38:09 +00001966#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001967PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001968"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001969Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001970
Barry Warsaw53699e91996-12-10 23:23:01 +00001971static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001972posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001973{
Mark Hammondef8b6542001-05-13 08:04:26 +00001974 char *path = NULL;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001975 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001976 int res;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001977 if (!PyArg_ParseTuple(args, "etll:chown",
Tim Peters5aa91602002-01-30 05:46:57 +00001978 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001979 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001980 return NULL;
1981 Py_BEGIN_ALLOW_THREADS
1982 res = chown(path, (uid_t) uid, (gid_t) gid);
1983 Py_END_ALLOW_THREADS
1984 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001985 return posix_error_with_allocated_filename(path);
1986 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001987 Py_INCREF(Py_None);
1988 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001989}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001990#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001991
Christian Heimes36281872007-11-30 21:11:28 +00001992#ifdef HAVE_FCHOWN
1993PyDoc_STRVAR(posix_fchown__doc__,
1994"fchown(fd, uid, gid)\n\n\
1995Change the owner and group id of the file given by file descriptor\n\
1996fd to the numeric uid and gid.");
1997
1998static PyObject *
1999posix_fchown(PyObject *self, PyObject *args)
2000{
2001 int fd, uid, gid;
2002 int res;
2003 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
2004 return NULL;
2005 Py_BEGIN_ALLOW_THREADS
2006 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2007 Py_END_ALLOW_THREADS
2008 if (res < 0)
2009 return posix_error();
2010 Py_RETURN_NONE;
2011}
2012#endif /* HAVE_FCHOWN */
2013
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002014#ifdef HAVE_LCHOWN
2015PyDoc_STRVAR(posix_lchown__doc__,
2016"lchown(path, uid, gid)\n\n\
2017Change the owner and group id of path to the numeric uid and gid.\n\
2018This function will not follow symbolic links.");
2019
2020static PyObject *
2021posix_lchown(PyObject *self, PyObject *args)
2022{
2023 char *path = NULL;
2024 int uid, gid;
2025 int res;
2026 if (!PyArg_ParseTuple(args, "etii:lchown",
2027 Py_FileSystemDefaultEncoding, &path,
2028 &uid, &gid))
2029 return NULL;
2030 Py_BEGIN_ALLOW_THREADS
2031 res = lchown(path, (uid_t) uid, (gid_t) gid);
2032 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00002033 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002034 return posix_error_with_allocated_filename(path);
2035 PyMem_Free(path);
2036 Py_INCREF(Py_None);
2037 return Py_None;
2038}
2039#endif /* HAVE_LCHOWN */
2040
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002041
Guido van Rossum36bc6801995-06-14 22:54:23 +00002042#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002043PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002044"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002045Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002046
Barry Warsaw53699e91996-12-10 23:23:01 +00002047static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002048posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002049{
Facundo Batista5596b0c2008-06-22 13:36:20 +00002050 int bufsize_incr = 1024;
2051 int bufsize = 0;
2052 char *tmpbuf = NULL;
2053 char *res = NULL;
2054 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00002055
Barry Warsaw53699e91996-12-10 23:23:01 +00002056 Py_BEGIN_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002057 do {
2058 bufsize = bufsize + bufsize_incr;
2059 tmpbuf = malloc(bufsize);
2060 if (tmpbuf == NULL) {
2061 break;
2062 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002063#if defined(PYOS_OS2) && defined(PYCC_GCC)
Facundo Batista5596b0c2008-06-22 13:36:20 +00002064 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002065#else
Facundo Batista5596b0c2008-06-22 13:36:20 +00002066 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002067#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00002068
2069 if (res == NULL) {
2070 free(tmpbuf);
2071 }
2072 } while ((res == NULL) && (errno == ERANGE));
Barry Warsaw53699e91996-12-10 23:23:01 +00002073 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002074
Guido van Rossumff4949e1992-08-05 19:58:53 +00002075 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002076 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002077
2078 dynamic_return = PyString_FromString(tmpbuf);
2079 free(tmpbuf);
2080
2081 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002082}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002083
Walter Dörwald3b918c32002-11-21 20:18:46 +00002084#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002085PyDoc_STRVAR(posix_getcwdu__doc__,
2086"getcwdu() -> path\n\n\
2087Return a unicode string representing the current working directory.");
2088
2089static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002090posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002091{
2092 char buf[1026];
2093 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002094
2095#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002096 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002097 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002098 wchar_t wbuf[1026];
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002099 wchar_t *wbuf2 = wbuf;
2100 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002101 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002102 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2103 /* If the buffer is large enough, len does not include the
2104 terminating \0. If the buffer is too small, len includes
2105 the space needed for the terminator. */
2106 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2107 wbuf2 = malloc(len * sizeof(wchar_t));
2108 if (wbuf2)
2109 len = GetCurrentDirectoryW(len, wbuf2);
2110 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002111 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002112 if (!wbuf2) {
2113 PyErr_NoMemory();
2114 return NULL;
2115 }
2116 if (!len) {
2117 if (wbuf2 != wbuf) free(wbuf2);
2118 return win32_error("getcwdu", NULL);
2119 }
2120 resobj = PyUnicode_FromWideChar(wbuf2, len);
2121 if (wbuf2 != wbuf) free(wbuf2);
2122 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002123 }
2124#endif
2125
2126 Py_BEGIN_ALLOW_THREADS
2127#if defined(PYOS_OS2) && defined(PYCC_GCC)
2128 res = _getcwd2(buf, sizeof buf);
2129#else
2130 res = getcwd(buf, sizeof buf);
2131#endif
2132 Py_END_ALLOW_THREADS
2133 if (res == NULL)
2134 return posix_error();
2135 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2136}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002137#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00002138#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002139
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002140
Guido van Rossumb6775db1994-08-01 11:34:53 +00002141#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002142PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002143"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002144Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002145
Barry Warsaw53699e91996-12-10 23:23:01 +00002146static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002147posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002148{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002149 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002150}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002151#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002152
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002153
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002154PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002155"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002156Return a list containing the names of the entries in the directory.\n\
2157\n\
2158 path: path of directory to list\n\
2159\n\
2160The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002161entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002162
Barry Warsaw53699e91996-12-10 23:23:01 +00002163static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002164posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002165{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002166 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002167 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002168#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002169
Barry Warsaw53699e91996-12-10 23:23:01 +00002170 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002171 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002172 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002173 WIN32_FIND_DATA FileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002174 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002175 char *bufptr = namebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002176 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002177
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002178#ifdef Py_WIN_WIDE_FILENAMES
2179 /* If on wide-character-capable OS see if argument
2180 is Unicode and if so use wide API. */
2181 if (unicode_file_names()) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002182 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002183 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2184 WIN32_FIND_DATAW wFileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002185 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002186 Py_UNICODE wch;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002187 /* Overallocate for \\*.*\0 */
2188 len = PyUnicode_GET_SIZE(po);
2189 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2190 if (!wnamebuf) {
2191 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002192 return NULL;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002193 }
2194 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2195 wch = len > 0 ? wnamebuf[len-1] : '\0';
2196 if (wch != L'/' && wch != L'\\' && wch != L':')
2197 wnamebuf[len++] = L'\\';
2198 wcscpy(wnamebuf + len, L"*.*");
2199 if ((d = PyList_New(0)) == NULL) {
2200 free(wnamebuf);
2201 return NULL;
2202 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002203 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2204 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002205 int error = GetLastError();
2206 if (error == ERROR_FILE_NOT_FOUND) {
2207 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002208 return d;
2209 }
2210 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002211 win32_error_unicode("FindFirstFileW", wnamebuf);
2212 free(wnamebuf);
2213 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002214 }
2215 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002216 /* Skip over . and .. */
2217 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2218 wcscmp(wFileData.cFileName, L"..") != 0) {
2219 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2220 if (v == NULL) {
2221 Py_DECREF(d);
2222 d = NULL;
2223 break;
2224 }
2225 if (PyList_Append(d, v) != 0) {
2226 Py_DECREF(v);
2227 Py_DECREF(d);
2228 d = NULL;
2229 break;
2230 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002231 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002232 }
Georg Brandl622927b2006-03-07 12:48:03 +00002233 Py_BEGIN_ALLOW_THREADS
2234 result = FindNextFileW(hFindFile, &wFileData);
2235 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002236 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2237 it got to the end of the directory. */
2238 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2239 Py_DECREF(d);
2240 win32_error_unicode("FindNextFileW", wnamebuf);
2241 FindClose(hFindFile);
2242 free(wnamebuf);
2243 return NULL;
2244 }
Georg Brandl622927b2006-03-07 12:48:03 +00002245 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002246
2247 if (FindClose(hFindFile) == FALSE) {
2248 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002249 win32_error_unicode("FindClose", wnamebuf);
2250 free(wnamebuf);
2251 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002252 }
Martin v. Löwise3edaea2006-05-15 05:51:36 +00002253 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002254 return d;
2255 }
2256 /* Drop the argument parsing error as narrow strings
2257 are also valid. */
2258 PyErr_Clear();
2259 }
2260#endif
2261
Tim Peters5aa91602002-01-30 05:46:57 +00002262 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002263 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002264 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002265 if (len > 0) {
2266 char ch = namebuf[len-1];
2267 if (ch != SEP && ch != ALTSEP && ch != ':')
2268 namebuf[len++] = '/';
2269 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002270 strcpy(namebuf + len, "*.*");
2271
Barry Warsaw53699e91996-12-10 23:23:01 +00002272 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002273 return NULL;
2274
2275 hFindFile = FindFirstFile(namebuf, &FileData);
2276 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002277 int error = GetLastError();
2278 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002279 return d;
2280 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002281 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002282 }
2283 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002284 /* Skip over . and .. */
2285 if (strcmp(FileData.cFileName, ".") != 0 &&
2286 strcmp(FileData.cFileName, "..") != 0) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002287 v = PyString_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002288 if (v == NULL) {
2289 Py_DECREF(d);
2290 d = NULL;
2291 break;
2292 }
2293 if (PyList_Append(d, v) != 0) {
2294 Py_DECREF(v);
2295 Py_DECREF(d);
2296 d = NULL;
2297 break;
2298 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002299 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002300 }
Georg Brandl622927b2006-03-07 12:48:03 +00002301 Py_BEGIN_ALLOW_THREADS
2302 result = FindNextFile(hFindFile, &FileData);
2303 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002304 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2305 it got to the end of the directory. */
2306 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2307 Py_DECREF(d);
2308 win32_error("FindNextFile", namebuf);
2309 FindClose(hFindFile);
2310 return NULL;
2311 }
Georg Brandl622927b2006-03-07 12:48:03 +00002312 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002313
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002314 if (FindClose(hFindFile) == FALSE) {
2315 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002316 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002317 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002318
2319 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002320
Tim Peters0bb44a42000-09-15 07:44:49 +00002321#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002322
2323#ifndef MAX_PATH
2324#define MAX_PATH CCHMAXPATH
2325#endif
2326 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002327 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002328 PyObject *d, *v;
2329 char namebuf[MAX_PATH+5];
2330 HDIR hdir = 1;
2331 ULONG srchcnt = 1;
2332 FILEFINDBUF3 ep;
2333 APIRET rc;
2334
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002335 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002336 return NULL;
2337 if (len >= MAX_PATH) {
2338 PyErr_SetString(PyExc_ValueError, "path too long");
2339 return NULL;
2340 }
2341 strcpy(namebuf, name);
2342 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002343 if (*pt == ALTSEP)
2344 *pt = SEP;
2345 if (namebuf[len-1] != SEP)
2346 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002347 strcpy(namebuf + len, "*.*");
2348
2349 if ((d = PyList_New(0)) == NULL)
2350 return NULL;
2351
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002352 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2353 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002354 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002355 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2356 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2357 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002358
2359 if (rc != NO_ERROR) {
2360 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002361 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002362 }
2363
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002364 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002365 do {
2366 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002367 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002368 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002369
2370 strcpy(namebuf, ep.achName);
2371
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002372 /* Leave Case of Name Alone -- In Native Form */
2373 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002374
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002375 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002376 if (v == NULL) {
2377 Py_DECREF(d);
2378 d = NULL;
2379 break;
2380 }
2381 if (PyList_Append(d, v) != 0) {
2382 Py_DECREF(v);
2383 Py_DECREF(d);
2384 d = NULL;
2385 break;
2386 }
2387 Py_DECREF(v);
2388 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2389 }
2390
2391 return d;
2392#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002393
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002394 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002395 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002396 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002397 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002398 int arg_is_unicode = 1;
2399
Georg Brandl05e89b82006-04-11 07:04:06 +00002400 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002401 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2402 arg_is_unicode = 0;
2403 PyErr_Clear();
2404 }
2405 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002406 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002407 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002408 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002409 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002410 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002411 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002412 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002413 return NULL;
2414 }
Georg Brandl622927b2006-03-07 12:48:03 +00002415 for (;;) {
Georg Brandl86cbf812008-07-16 21:31:41 +00002416 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002417 Py_BEGIN_ALLOW_THREADS
2418 ep = readdir(dirp);
2419 Py_END_ALLOW_THREADS
Georg Brandl86cbf812008-07-16 21:31:41 +00002420 if (ep == NULL) {
2421 if (errno == 0) {
2422 break;
2423 } else {
2424 closedir(dirp);
2425 Py_DECREF(d);
2426 return posix_error_with_allocated_filename(name);
2427 }
2428 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002429 if (ep->d_name[0] == '.' &&
2430 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002431 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002432 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002433 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002434 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002435 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002436 d = NULL;
2437 break;
2438 }
Just van Rossum46c97842003-02-25 21:42:15 +00002439#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002440 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002441 PyObject *w;
2442
2443 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002444 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002445 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002446 if (w != NULL) {
2447 Py_DECREF(v);
2448 v = w;
2449 }
2450 else {
2451 /* fall back to the original byte string, as
2452 discussed in patch #683592 */
2453 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002454 }
Just van Rossum46c97842003-02-25 21:42:15 +00002455 }
2456#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002457 if (PyList_Append(d, v) != 0) {
2458 Py_DECREF(v);
2459 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002460 d = NULL;
2461 break;
2462 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002463 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002464 }
2465 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002466 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002467
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002468 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002469
Tim Peters0bb44a42000-09-15 07:44:49 +00002470#endif /* which OS */
2471} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002472
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002473#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002474/* A helper function for abspath on win32 */
2475static PyObject *
2476posix__getfullpathname(PyObject *self, PyObject *args)
2477{
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00002478 /* assume encoded strings won't more than double no of chars */
Mark Hammondef8b6542001-05-13 08:04:26 +00002479 char inbuf[MAX_PATH*2];
2480 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002481 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002482 char outbuf[MAX_PATH*2];
2483 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002484#ifdef Py_WIN_WIDE_FILENAMES
2485 if (unicode_file_names()) {
2486 PyUnicodeObject *po;
2487 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
Hirokazu Yamamotoed29bb42008-11-08 03:46:17 +00002488 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2489 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002490 Py_UNICODE *wtemp;
Hirokazu Yamamotoed29bb42008-11-08 03:46:17 +00002491 DWORD result;
2492 PyObject *v;
2493 result = GetFullPathNameW(wpath,
2494 sizeof(woutbuf)/sizeof(woutbuf[0]),
2495 woutbuf, &wtemp);
2496 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2497 woutbufp = malloc(result * sizeof(Py_UNICODE));
2498 if (!woutbufp)
2499 return PyErr_NoMemory();
2500 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2501 }
2502 if (result)
2503 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2504 else
2505 v = win32_error_unicode("GetFullPathNameW", wpath);
2506 if (woutbufp != woutbuf)
2507 free(woutbufp);
2508 return v;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002509 }
2510 /* Drop the argument parsing error as narrow strings
2511 are also valid. */
2512 PyErr_Clear();
2513 }
2514#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002515 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2516 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002517 &insize))
2518 return NULL;
2519 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2520 outbuf, &temp))
2521 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002522 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2523 return PyUnicode_Decode(outbuf, strlen(outbuf),
2524 Py_FileSystemDefaultEncoding, NULL);
2525 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002526 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002527} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002528#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002529
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002530PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002531"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002532Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002533
Barry Warsaw53699e91996-12-10 23:23:01 +00002534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002535posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002536{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002537 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002538 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002539 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002540
2541#ifdef Py_WIN_WIDE_FILENAMES
2542 if (unicode_file_names()) {
2543 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002544 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002545 Py_BEGIN_ALLOW_THREADS
2546 /* PyUnicode_AS_UNICODE OK without thread lock as
2547 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002548 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002549 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002550 if (!res)
2551 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002552 Py_INCREF(Py_None);
2553 return Py_None;
2554 }
2555 /* Drop the argument parsing error as narrow strings
2556 are also valid. */
2557 PyErr_Clear();
2558 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002559 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2560 Py_FileSystemDefaultEncoding, &path, &mode))
2561 return NULL;
2562 Py_BEGIN_ALLOW_THREADS
2563 /* PyUnicode_AS_UNICODE OK without thread lock as
2564 it is a simple dereference. */
2565 res = CreateDirectoryA(path, NULL);
2566 Py_END_ALLOW_THREADS
2567 if (!res) {
2568 win32_error("mkdir", path);
2569 PyMem_Free(path);
2570 return NULL;
2571 }
2572 PyMem_Free(path);
2573 Py_INCREF(Py_None);
2574 return Py_None;
2575#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002576
Tim Peters5aa91602002-01-30 05:46:57 +00002577 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002578 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002579 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002580 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002581#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002582 res = mkdir(path);
2583#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002584 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002585#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002586 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002587 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002588 return posix_error_with_allocated_filename(path);
2589 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002590 Py_INCREF(Py_None);
2591 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002592#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002593}
2594
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002595
Neal Norwitz1818ed72006-03-26 00:29:48 +00002596/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2597#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002598#include <sys/resource.h>
2599#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002600
Neal Norwitz1818ed72006-03-26 00:29:48 +00002601
2602#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002603PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002604"nice(inc) -> new_priority\n\n\
2605Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002606
Barry Warsaw53699e91996-12-10 23:23:01 +00002607static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002608posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002609{
2610 int increment, value;
2611
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002612 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002613 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002614
2615 /* There are two flavours of 'nice': one that returns the new
2616 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002617 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2618 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002619
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002620 If we are of the nice family that returns the new priority, we
2621 need to clear errno before the call, and check if errno is filled
2622 before calling posix_error() on a returnvalue of -1, because the
2623 -1 may be the actual new priority! */
2624
2625 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002626 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002627#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002628 if (value == 0)
2629 value = getpriority(PRIO_PROCESS, 0);
2630#endif
2631 if (value == -1 && errno != 0)
2632 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002633 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002634 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002635}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002636#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002637
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002638PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002639"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002640Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002641
Barry Warsaw53699e91996-12-10 23:23:01 +00002642static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002643posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002644{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002645#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002646 PyObject *o1, *o2;
2647 char *p1, *p2;
2648 BOOL result;
2649 if (unicode_file_names()) {
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002650 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2651 goto error;
2652 if (!convert_to_unicode(&o1))
2653 goto error;
2654 if (!convert_to_unicode(&o2)) {
2655 Py_DECREF(o1);
2656 goto error;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002657 }
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002658 Py_BEGIN_ALLOW_THREADS
2659 result = MoveFileW(PyUnicode_AsUnicode(o1),
2660 PyUnicode_AsUnicode(o2));
2661 Py_END_ALLOW_THREADS
2662 Py_DECREF(o1);
2663 Py_DECREF(o2);
2664 if (!result)
2665 return win32_error("rename", NULL);
2666 Py_INCREF(Py_None);
2667 return Py_None;
2668error:
2669 PyErr_Clear();
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002670 }
2671 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2672 return NULL;
2673 Py_BEGIN_ALLOW_THREADS
2674 result = MoveFileA(p1, p2);
2675 Py_END_ALLOW_THREADS
2676 if (!result)
2677 return win32_error("rename", NULL);
2678 Py_INCREF(Py_None);
2679 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002680#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002681 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002682#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002683}
2684
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002685
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002686PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002687"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002688Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002689
Barry Warsaw53699e91996-12-10 23:23:01 +00002690static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002691posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002692{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002693#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002694 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002695#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002696 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002697#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002698}
2699
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002700
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002701PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002702"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002703Perform a stat system call on the given path.");
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_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002707{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002708#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002709 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002710#else
2711 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2712#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002713}
2714
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002715
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002716#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002717PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002718"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002719Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002720
Barry Warsaw53699e91996-12-10 23:23:01 +00002721static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002722posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002723{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002724 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002725 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002726 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002727 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002728 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002729 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002730 Py_END_ALLOW_THREADS
2731 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002732}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002733#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002734
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002735
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002736PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002737"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002738Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002739
Barry Warsaw53699e91996-12-10 23:23:01 +00002740static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002741posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002742{
2743 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002744 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002745 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002746 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002747 if (i < 0)
2748 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002749 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002750}
2751
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002752
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002753PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002754"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002755Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002756
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002757PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002758"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002759Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002760
Barry Warsaw53699e91996-12-10 23:23:01 +00002761static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002762posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002763{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002764#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002765 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002766#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002767 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002768#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002769}
2770
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002771
Guido van Rossumb6775db1994-08-01 11:34:53 +00002772#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002773PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002774"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002775Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002776
Barry Warsaw53699e91996-12-10 23:23:01 +00002777static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002778posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002779{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002780 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002781 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002782
Barry Warsaw53699e91996-12-10 23:23:01 +00002783 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002784 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002785 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002786 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002787 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002788 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002789 u.sysname,
2790 u.nodename,
2791 u.release,
2792 u.version,
2793 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002794}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002795#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002796
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002797static int
2798extract_time(PyObject *t, long* sec, long* usec)
2799{
2800 long intval;
2801 if (PyFloat_Check(t)) {
2802 double tval = PyFloat_AsDouble(t);
Christian Heimese93237d2007-12-19 02:37:44 +00002803 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002804 if (!intobj)
2805 return -1;
2806 intval = PyInt_AsLong(intobj);
2807 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002808 if (intval == -1 && PyErr_Occurred())
2809 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002810 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002811 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002812 if (*usec < 0)
2813 /* If rounding gave us a negative number,
2814 truncate. */
2815 *usec = 0;
2816 return 0;
2817 }
2818 intval = PyInt_AsLong(t);
2819 if (intval == -1 && PyErr_Occurred())
2820 return -1;
2821 *sec = intval;
2822 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002823 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002824}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002825
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002826PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002827"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002828utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002829Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002830second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002831
Barry Warsaw53699e91996-12-10 23:23:01 +00002832static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002833posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002834{
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002835#ifdef Py_WIN_WIDE_FILENAMES
2836 PyObject *arg;
2837 PyUnicodeObject *obwpath;
2838 wchar_t *wpath = NULL;
2839 char *apath = NULL;
2840 HANDLE hFile;
2841 long atimesec, mtimesec, ausec, musec;
2842 FILETIME atime, mtime;
2843 PyObject *result = NULL;
2844
2845 if (unicode_file_names()) {
2846 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2847 wpath = PyUnicode_AS_UNICODE(obwpath);
2848 Py_BEGIN_ALLOW_THREADS
2849 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002850 NULL, OPEN_EXISTING,
2851 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002852 Py_END_ALLOW_THREADS
2853 if (hFile == INVALID_HANDLE_VALUE)
2854 return win32_error_unicode("utime", wpath);
2855 } else
2856 /* Drop the argument parsing error as narrow strings
2857 are also valid. */
2858 PyErr_Clear();
2859 }
2860 if (!wpath) {
2861 if (!PyArg_ParseTuple(args, "etO:utime",
2862 Py_FileSystemDefaultEncoding, &apath, &arg))
2863 return NULL;
2864 Py_BEGIN_ALLOW_THREADS
2865 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002866 NULL, OPEN_EXISTING,
2867 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002868 Py_END_ALLOW_THREADS
2869 if (hFile == INVALID_HANDLE_VALUE) {
2870 win32_error("utime", apath);
2871 PyMem_Free(apath);
2872 return NULL;
2873 }
2874 PyMem_Free(apath);
2875 }
2876
2877 if (arg == Py_None) {
2878 SYSTEMTIME now;
2879 GetSystemTime(&now);
2880 if (!SystemTimeToFileTime(&now, &mtime) ||
2881 !SystemTimeToFileTime(&now, &atime)) {
2882 win32_error("utime", NULL);
2883 goto done;
2884 }
2885 }
2886 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2887 PyErr_SetString(PyExc_TypeError,
2888 "utime() arg 2 must be a tuple (atime, mtime)");
2889 goto done;
2890 }
2891 else {
2892 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2893 &atimesec, &ausec) == -1)
2894 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002895 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002896 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2897 &mtimesec, &musec) == -1)
2898 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002899 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002900 }
2901 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2902 /* Avoid putting the file name into the error here,
2903 as that may confuse the user into believing that
2904 something is wrong with the file, when it also
2905 could be the time stamp that gives a problem. */
2906 win32_error("utime", NULL);
2907 }
2908 Py_INCREF(Py_None);
2909 result = Py_None;
2910done:
2911 CloseHandle(hFile);
2912 return result;
2913#else /* Py_WIN_WIDE_FILENAMES */
2914
Neal Norwitz2adf2102004-06-09 01:46:02 +00002915 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002916 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002917 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002918 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002919
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002920#if defined(HAVE_UTIMES)
2921 struct timeval buf[2];
2922#define ATIME buf[0].tv_sec
2923#define MTIME buf[1].tv_sec
2924#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002925/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002926 struct utimbuf buf;
2927#define ATIME buf.actime
2928#define MTIME buf.modtime
2929#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002930#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002931 time_t buf[2];
2932#define ATIME buf[0]
2933#define MTIME buf[1]
2934#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002935#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002936
Mark Hammond817c9292003-12-03 01:22:38 +00002937
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002938 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002939 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002940 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002941 if (arg == Py_None) {
2942 /* optional time values not given */
2943 Py_BEGIN_ALLOW_THREADS
2944 res = utime(path, NULL);
2945 Py_END_ALLOW_THREADS
2946 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002947 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002948 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002949 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002950 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002951 return NULL;
2952 }
2953 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002954 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002955 &atime, &ausec) == -1) {
2956 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002957 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002958 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002959 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002960 &mtime, &musec) == -1) {
2961 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002962 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002963 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002964 ATIME = atime;
2965 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002966#ifdef HAVE_UTIMES
2967 buf[0].tv_usec = ausec;
2968 buf[1].tv_usec = musec;
2969 Py_BEGIN_ALLOW_THREADS
2970 res = utimes(path, buf);
2971 Py_END_ALLOW_THREADS
2972#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002973 Py_BEGIN_ALLOW_THREADS
2974 res = utime(path, UTIME_ARG);
2975 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002976#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002977 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002978 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002979 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002980 }
Neal Norwitz96652712004-06-06 20:40:27 +00002981 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002982 Py_INCREF(Py_None);
2983 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002984#undef UTIME_ARG
2985#undef ATIME
2986#undef MTIME
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002987#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002988}
2989
Guido van Rossum85e3b011991-06-03 12:42:10 +00002990
Guido van Rossum3b066191991-06-04 19:40:25 +00002991/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002992
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002993PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002994"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002995Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002996
Barry Warsaw53699e91996-12-10 23:23:01 +00002997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002998posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002999{
3000 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003001 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003002 return NULL;
3003 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00003004 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003005}
3006
Martin v. Löwis114619e2002-10-07 06:44:21 +00003007#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3008static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003009free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003010{
Martin v. Löwis725507b2006-03-07 12:08:51 +00003011 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00003012 for (i = 0; i < count; i++)
3013 PyMem_Free(array[i]);
3014 PyMem_DEL(array);
3015}
3016#endif
3017
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003018
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003019#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003020PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003021"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003022Execute an executable path with arguments, replacing current process.\n\
3023\n\
3024 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003025 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003026
Barry Warsaw53699e91996-12-10 23:23:01 +00003027static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003028posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003029{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003030 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003031 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003032 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003033 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003034 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003035
Guido van Rossum89b33251993-10-22 14:26:06 +00003036 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00003037 argv is a list or tuple of strings. */
3038
Martin v. Löwis114619e2002-10-07 06:44:21 +00003039 if (!PyArg_ParseTuple(args, "etO:execv",
3040 Py_FileSystemDefaultEncoding,
3041 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003042 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003043 if (PyList_Check(argv)) {
3044 argc = PyList_Size(argv);
3045 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003046 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003047 else if (PyTuple_Check(argv)) {
3048 argc = PyTuple_Size(argv);
3049 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003050 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003051 else {
Fred Drake661ea262000-10-24 19:57:45 +00003052 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003053 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00003054 return NULL;
3055 }
3056
Barry Warsaw53699e91996-12-10 23:23:01 +00003057 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003058 if (argvlist == NULL) {
3059 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003060 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003061 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003062 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003063 if (!PyArg_Parse((*getitem)(argv, i), "et",
3064 Py_FileSystemDefaultEncoding,
3065 &argvlist[i])) {
3066 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00003067 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00003068 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003069 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00003070 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003071
Guido van Rossum85e3b011991-06-03 12:42:10 +00003072 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003073 }
3074 argvlist[argc] = NULL;
3075
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003076 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003077
Guido van Rossum85e3b011991-06-03 12:42:10 +00003078 /* If we get here it's definitely an error */
3079
Martin v. Löwis114619e2002-10-07 06:44:21 +00003080 free_string_array(argvlist, argc);
3081 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003082 return posix_error();
3083}
3084
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003085
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003086PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003087"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003088Execute a path with arguments and environment, replacing current process.\n\
3089\n\
3090 path: path of executable file\n\
3091 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003092 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003093
Barry Warsaw53699e91996-12-10 23:23:01 +00003094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003095posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003096{
3097 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003098 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003099 char **argvlist;
3100 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003101 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003102 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003103 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003104 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003105
3106 /* execve has three arguments: (path, argv, env), where
3107 argv is a list or tuple of strings and env is a dictionary
3108 like posix.environ. */
3109
Martin v. Löwis114619e2002-10-07 06:44:21 +00003110 if (!PyArg_ParseTuple(args, "etOO:execve",
3111 Py_FileSystemDefaultEncoding,
3112 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003113 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003114 if (PyList_Check(argv)) {
3115 argc = PyList_Size(argv);
3116 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003117 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003118 else if (PyTuple_Check(argv)) {
3119 argc = PyTuple_Size(argv);
3120 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003121 }
3122 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003123 PyErr_SetString(PyExc_TypeError,
3124 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003125 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003126 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003127 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003128 PyErr_SetString(PyExc_TypeError,
3129 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003130 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003131 }
3132
Barry Warsaw53699e91996-12-10 23:23:01 +00003133 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003134 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003135 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003136 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003137 }
3138 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003139 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003140 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003141 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003142 &argvlist[i]))
3143 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003144 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003145 goto fail_1;
3146 }
3147 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003148 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003149 argvlist[argc] = NULL;
3150
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003151 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003152 if (i < 0)
3153 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003154 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003155 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003156 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003157 goto fail_1;
3158 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003159 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003160 keys = PyMapping_Keys(env);
3161 vals = PyMapping_Values(env);
3162 if (!keys || !vals)
3163 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003164 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3165 PyErr_SetString(PyExc_TypeError,
3166 "execve(): env.keys() or env.values() is not a list");
3167 goto fail_2;
3168 }
Tim Peters5aa91602002-01-30 05:46:57 +00003169
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003170 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003171 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003172 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003173
3174 key = PyList_GetItem(keys, pos);
3175 val = PyList_GetItem(vals, pos);
3176 if (!key || !val)
3177 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003178
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003179 if (!PyArg_Parse(
3180 key,
3181 "s;execve() arg 3 contains a non-string key",
3182 &k) ||
3183 !PyArg_Parse(
3184 val,
3185 "s;execve() arg 3 contains a non-string value",
3186 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003187 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003188 goto fail_2;
3189 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003190
3191#if defined(PYOS_OS2)
3192 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3193 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3194#endif
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003195 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003196 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003197 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003198 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003199 goto fail_2;
3200 }
Tim Petersc8996f52001-12-03 20:41:00 +00003201 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003202 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003203#if defined(PYOS_OS2)
3204 }
3205#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003206 }
3207 envlist[envc] = 0;
3208
3209 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003210
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003211 /* If we get here it's definitely an error */
3212
3213 (void) posix_error();
3214
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003215 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003216 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003217 PyMem_DEL(envlist[envc]);
3218 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003219 fail_1:
3220 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003221 Py_XDECREF(vals);
3222 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003223 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003224 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003225 return NULL;
3226}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003227#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003228
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003229
Guido van Rossuma1065681999-01-25 23:20:23 +00003230#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003231PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003232"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003233Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003234\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003235 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003236 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003237 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003238
3239static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003240posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003241{
3242 char *path;
3243 PyObject *argv;
3244 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003245 int mode, i;
3246 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003247 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003248 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003249
3250 /* spawnv has three arguments: (mode, path, argv), where
3251 argv is a list or tuple of strings. */
3252
Martin v. Löwis114619e2002-10-07 06:44:21 +00003253 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3254 Py_FileSystemDefaultEncoding,
3255 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003256 return NULL;
3257 if (PyList_Check(argv)) {
3258 argc = PyList_Size(argv);
3259 getitem = PyList_GetItem;
3260 }
3261 else if (PyTuple_Check(argv)) {
3262 argc = PyTuple_Size(argv);
3263 getitem = PyTuple_GetItem;
3264 }
3265 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003266 PyErr_SetString(PyExc_TypeError,
3267 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003268 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003269 return NULL;
3270 }
3271
3272 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003273 if (argvlist == NULL) {
3274 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003275 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003276 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003277 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003278 if (!PyArg_Parse((*getitem)(argv, i), "et",
3279 Py_FileSystemDefaultEncoding,
3280 &argvlist[i])) {
3281 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003282 PyErr_SetString(
3283 PyExc_TypeError,
3284 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003285 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003286 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003287 }
3288 }
3289 argvlist[argc] = NULL;
3290
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003291#if defined(PYOS_OS2) && defined(PYCC_GCC)
3292 Py_BEGIN_ALLOW_THREADS
3293 spawnval = spawnv(mode, path, argvlist);
3294 Py_END_ALLOW_THREADS
3295#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003296 if (mode == _OLD_P_OVERLAY)
3297 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003298
Tim Peters25059d32001-12-07 20:35:43 +00003299 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003300 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003301 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003302#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003303
Martin v. Löwis114619e2002-10-07 06:44:21 +00003304 free_string_array(argvlist, argc);
3305 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003306
Fred Drake699f3522000-06-29 21:12:41 +00003307 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003308 return posix_error();
3309 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003310#if SIZEOF_LONG == SIZEOF_VOID_P
3311 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003312#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003313 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003314#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003315}
3316
3317
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003318PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003319"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003320Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003321\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003322 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003323 path: path of executable file\n\
3324 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003325 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003326
3327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003328posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003329{
3330 char *path;
3331 PyObject *argv, *env;
3332 char **argvlist;
3333 char **envlist;
3334 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003335 int mode, pos, envc;
3336 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003337 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003338 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003339 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003340
3341 /* spawnve has four arguments: (mode, path, argv, env), where
3342 argv is a list or tuple of strings and env is a dictionary
3343 like posix.environ. */
3344
Martin v. Löwis114619e2002-10-07 06:44:21 +00003345 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3346 Py_FileSystemDefaultEncoding,
3347 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003348 return NULL;
3349 if (PyList_Check(argv)) {
3350 argc = PyList_Size(argv);
3351 getitem = PyList_GetItem;
3352 }
3353 else if (PyTuple_Check(argv)) {
3354 argc = PyTuple_Size(argv);
3355 getitem = PyTuple_GetItem;
3356 }
3357 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003358 PyErr_SetString(PyExc_TypeError,
3359 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003360 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003361 }
3362 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003363 PyErr_SetString(PyExc_TypeError,
3364 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003365 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003366 }
3367
3368 argvlist = PyMem_NEW(char *, argc+1);
3369 if (argvlist == NULL) {
3370 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003371 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003372 }
3373 for (i = 0; i < argc; i++) {
3374 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003375 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003376 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003377 &argvlist[i]))
3378 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003379 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003380 goto fail_1;
3381 }
3382 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003383 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003384 argvlist[argc] = NULL;
3385
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003386 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003387 if (i < 0)
3388 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003389 envlist = PyMem_NEW(char *, i + 1);
3390 if (envlist == NULL) {
3391 PyErr_NoMemory();
3392 goto fail_1;
3393 }
3394 envc = 0;
3395 keys = PyMapping_Keys(env);
3396 vals = PyMapping_Values(env);
3397 if (!keys || !vals)
3398 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003399 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3400 PyErr_SetString(PyExc_TypeError,
3401 "spawnve(): env.keys() or env.values() is not a list");
3402 goto fail_2;
3403 }
Tim Peters5aa91602002-01-30 05:46:57 +00003404
Guido van Rossuma1065681999-01-25 23:20:23 +00003405 for (pos = 0; pos < i; pos++) {
3406 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003407 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003408
3409 key = PyList_GetItem(keys, pos);
3410 val = PyList_GetItem(vals, pos);
3411 if (!key || !val)
3412 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003413
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003414 if (!PyArg_Parse(
3415 key,
3416 "s;spawnve() arg 3 contains a non-string key",
3417 &k) ||
3418 !PyArg_Parse(
3419 val,
3420 "s;spawnve() arg 3 contains a non-string value",
3421 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003422 {
3423 goto fail_2;
3424 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003425 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003426 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003427 if (p == NULL) {
3428 PyErr_NoMemory();
3429 goto fail_2;
3430 }
Tim Petersc8996f52001-12-03 20:41:00 +00003431 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003432 envlist[envc++] = p;
3433 }
3434 envlist[envc] = 0;
3435
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003436#if defined(PYOS_OS2) && defined(PYCC_GCC)
3437 Py_BEGIN_ALLOW_THREADS
3438 spawnval = spawnve(mode, path, argvlist, envlist);
3439 Py_END_ALLOW_THREADS
3440#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003441 if (mode == _OLD_P_OVERLAY)
3442 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003443
3444 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003445 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003446 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003447#endif
Tim Peters25059d32001-12-07 20:35:43 +00003448
Fred Drake699f3522000-06-29 21:12:41 +00003449 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003450 (void) posix_error();
3451 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003452#if SIZEOF_LONG == SIZEOF_VOID_P
3453 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003454#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003455 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003456#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003457
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003458 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003459 while (--envc >= 0)
3460 PyMem_DEL(envlist[envc]);
3461 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003462 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003463 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003464 Py_XDECREF(vals);
3465 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003466 fail_0:
3467 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003468 return res;
3469}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003470
3471/* OS/2 supports spawnvp & spawnvpe natively */
3472#if defined(PYOS_OS2)
3473PyDoc_STRVAR(posix_spawnvp__doc__,
3474"spawnvp(mode, file, args)\n\n\
3475Execute the program 'file' in a new process, using the environment\n\
3476search path to find the file.\n\
3477\n\
3478 mode: mode of process creation\n\
3479 file: executable file name\n\
3480 args: tuple or list of strings");
3481
3482static PyObject *
3483posix_spawnvp(PyObject *self, PyObject *args)
3484{
3485 char *path;
3486 PyObject *argv;
3487 char **argvlist;
3488 int mode, i, argc;
3489 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003490 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003491
3492 /* spawnvp has three arguments: (mode, path, argv), where
3493 argv is a list or tuple of strings. */
3494
3495 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3496 Py_FileSystemDefaultEncoding,
3497 &path, &argv))
3498 return NULL;
3499 if (PyList_Check(argv)) {
3500 argc = PyList_Size(argv);
3501 getitem = PyList_GetItem;
3502 }
3503 else if (PyTuple_Check(argv)) {
3504 argc = PyTuple_Size(argv);
3505 getitem = PyTuple_GetItem;
3506 }
3507 else {
3508 PyErr_SetString(PyExc_TypeError,
3509 "spawnvp() arg 2 must be a tuple or list");
3510 PyMem_Free(path);
3511 return NULL;
3512 }
3513
3514 argvlist = PyMem_NEW(char *, argc+1);
3515 if (argvlist == NULL) {
3516 PyMem_Free(path);
3517 return PyErr_NoMemory();
3518 }
3519 for (i = 0; i < argc; i++) {
3520 if (!PyArg_Parse((*getitem)(argv, i), "et",
3521 Py_FileSystemDefaultEncoding,
3522 &argvlist[i])) {
3523 free_string_array(argvlist, i);
3524 PyErr_SetString(
3525 PyExc_TypeError,
3526 "spawnvp() arg 2 must contain only strings");
3527 PyMem_Free(path);
3528 return NULL;
3529 }
3530 }
3531 argvlist[argc] = NULL;
3532
3533 Py_BEGIN_ALLOW_THREADS
3534#if defined(PYCC_GCC)
3535 spawnval = spawnvp(mode, path, argvlist);
3536#else
3537 spawnval = _spawnvp(mode, path, argvlist);
3538#endif
3539 Py_END_ALLOW_THREADS
3540
3541 free_string_array(argvlist, argc);
3542 PyMem_Free(path);
3543
3544 if (spawnval == -1)
3545 return posix_error();
3546 else
3547 return Py_BuildValue("l", (long) spawnval);
3548}
3549
3550
3551PyDoc_STRVAR(posix_spawnvpe__doc__,
3552"spawnvpe(mode, file, args, env)\n\n\
3553Execute the program 'file' in a new process, using the environment\n\
3554search path to find the file.\n\
3555\n\
3556 mode: mode of process creation\n\
3557 file: executable file name\n\
3558 args: tuple or list of arguments\n\
3559 env: dictionary of strings mapping to strings");
3560
3561static PyObject *
3562posix_spawnvpe(PyObject *self, PyObject *args)
3563{
3564 char *path;
3565 PyObject *argv, *env;
3566 char **argvlist;
3567 char **envlist;
3568 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3569 int mode, i, pos, argc, envc;
3570 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003571 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003572 int lastarg = 0;
3573
3574 /* spawnvpe has four arguments: (mode, path, argv, env), where
3575 argv is a list or tuple of strings and env is a dictionary
3576 like posix.environ. */
3577
3578 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3579 Py_FileSystemDefaultEncoding,
3580 &path, &argv, &env))
3581 return NULL;
3582 if (PyList_Check(argv)) {
3583 argc = PyList_Size(argv);
3584 getitem = PyList_GetItem;
3585 }
3586 else if (PyTuple_Check(argv)) {
3587 argc = PyTuple_Size(argv);
3588 getitem = PyTuple_GetItem;
3589 }
3590 else {
3591 PyErr_SetString(PyExc_TypeError,
3592 "spawnvpe() arg 2 must be a tuple or list");
3593 goto fail_0;
3594 }
3595 if (!PyMapping_Check(env)) {
3596 PyErr_SetString(PyExc_TypeError,
3597 "spawnvpe() arg 3 must be a mapping object");
3598 goto fail_0;
3599 }
3600
3601 argvlist = PyMem_NEW(char *, argc+1);
3602 if (argvlist == NULL) {
3603 PyErr_NoMemory();
3604 goto fail_0;
3605 }
3606 for (i = 0; i < argc; i++) {
3607 if (!PyArg_Parse((*getitem)(argv, i),
3608 "et;spawnvpe() arg 2 must contain only strings",
3609 Py_FileSystemDefaultEncoding,
3610 &argvlist[i]))
3611 {
3612 lastarg = i;
3613 goto fail_1;
3614 }
3615 }
3616 lastarg = argc;
3617 argvlist[argc] = NULL;
3618
3619 i = PyMapping_Size(env);
3620 if (i < 0)
3621 goto fail_1;
3622 envlist = PyMem_NEW(char *, i + 1);
3623 if (envlist == NULL) {
3624 PyErr_NoMemory();
3625 goto fail_1;
3626 }
3627 envc = 0;
3628 keys = PyMapping_Keys(env);
3629 vals = PyMapping_Values(env);
3630 if (!keys || !vals)
3631 goto fail_2;
3632 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3633 PyErr_SetString(PyExc_TypeError,
3634 "spawnvpe(): env.keys() or env.values() is not a list");
3635 goto fail_2;
3636 }
3637
3638 for (pos = 0; pos < i; pos++) {
3639 char *p, *k, *v;
3640 size_t len;
3641
3642 key = PyList_GetItem(keys, pos);
3643 val = PyList_GetItem(vals, pos);
3644 if (!key || !val)
3645 goto fail_2;
3646
3647 if (!PyArg_Parse(
3648 key,
3649 "s;spawnvpe() arg 3 contains a non-string key",
3650 &k) ||
3651 !PyArg_Parse(
3652 val,
3653 "s;spawnvpe() arg 3 contains a non-string value",
3654 &v))
3655 {
3656 goto fail_2;
3657 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003658 len = PyString_Size(key) + PyString_Size(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003659 p = PyMem_NEW(char, len);
3660 if (p == NULL) {
3661 PyErr_NoMemory();
3662 goto fail_2;
3663 }
3664 PyOS_snprintf(p, len, "%s=%s", k, v);
3665 envlist[envc++] = p;
3666 }
3667 envlist[envc] = 0;
3668
3669 Py_BEGIN_ALLOW_THREADS
3670#if defined(PYCC_GCC)
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003671 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003672#else
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003673 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003674#endif
3675 Py_END_ALLOW_THREADS
3676
3677 if (spawnval == -1)
3678 (void) posix_error();
3679 else
3680 res = Py_BuildValue("l", (long) spawnval);
3681
3682 fail_2:
3683 while (--envc >= 0)
3684 PyMem_DEL(envlist[envc]);
3685 PyMem_DEL(envlist);
3686 fail_1:
3687 free_string_array(argvlist, lastarg);
3688 Py_XDECREF(vals);
3689 Py_XDECREF(keys);
3690 fail_0:
3691 PyMem_Free(path);
3692 return res;
3693}
3694#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003695#endif /* HAVE_SPAWNV */
3696
3697
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003698#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003699PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003700"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003701Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3702\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003703Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003704
3705static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003706posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003707{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003708 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003709 if (pid == -1)
3710 return posix_error();
Gregory P. Smithfb7a50f2008-07-14 06:06:48 +00003711 if (pid == 0)
3712 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003713 return PyInt_FromLong(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003714}
3715#endif
3716
3717
Guido van Rossumad0ee831995-03-01 10:34:45 +00003718#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003719PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003720"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003721Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003722Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003723
Barry Warsaw53699e91996-12-10 23:23:01 +00003724static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003725posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003726{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003727 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003728 if (pid == -1)
3729 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003730 if (pid == 0)
3731 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003732 return PyInt_FromLong(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003733}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003734#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003735
Neal Norwitzb59798b2003-03-21 01:43:31 +00003736/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003737/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3738#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003739#define DEV_PTY_FILE "/dev/ptc"
3740#define HAVE_DEV_PTMX
3741#else
3742#define DEV_PTY_FILE "/dev/ptmx"
3743#endif
3744
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003745#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003746#ifdef HAVE_PTY_H
3747#include <pty.h>
3748#else
3749#ifdef HAVE_LIBUTIL_H
3750#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003751#endif /* HAVE_LIBUTIL_H */
3752#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003753#ifdef HAVE_STROPTS_H
3754#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003755#endif
3756#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003757
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003758#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003759PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003760"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003761Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003762
3763static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003764posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003765{
3766 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003767#ifndef HAVE_OPENPTY
3768 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003769#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003770#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003771 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003772#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003773 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003774#endif
3775#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003776
Thomas Wouters70c21a12000-07-14 14:28:33 +00003777#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003778 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3779 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003780#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003781 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3782 if (slave_name == NULL)
3783 return posix_error();
3784
3785 slave_fd = open(slave_name, O_RDWR);
3786 if (slave_fd < 0)
3787 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003788#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003789 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003790 if (master_fd < 0)
3791 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003792 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003793 /* change permission of slave */
3794 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003795 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003796 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003797 }
3798 /* unlock slave */
3799 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003800 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003801 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003802 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003803 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003804 slave_name = ptsname(master_fd); /* get name of slave */
3805 if (slave_name == NULL)
3806 return posix_error();
3807 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3808 if (slave_fd < 0)
3809 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003810#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003811 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3812 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003813#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003814 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003815#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003816#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003817#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003818
Fred Drake8cef4cf2000-06-28 16:40:38 +00003819 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003820
Fred Drake8cef4cf2000-06-28 16:40:38 +00003821}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003822#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003823
3824#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003825PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003826"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003827Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3828Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003829To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003830
3831static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003832posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003833{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003834 int master_fd = -1;
3835 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003836
Fred Drake8cef4cf2000-06-28 16:40:38 +00003837 pid = forkpty(&master_fd, NULL, NULL, NULL);
3838 if (pid == -1)
3839 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003840 if (pid == 0)
3841 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003842 return Py_BuildValue("(li)", pid, master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003843}
3844#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003845
Guido van Rossumad0ee831995-03-01 10:34:45 +00003846#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003847PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003848"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003849Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003850
Barry Warsaw53699e91996-12-10 23:23:01 +00003851static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003852posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003853{
Barry Warsaw53699e91996-12-10 23:23:01 +00003854 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003855}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003856#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003857
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003858
Guido van Rossumad0ee831995-03-01 10:34:45 +00003859#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003860PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003861"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003862Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003863
Barry Warsaw53699e91996-12-10 23:23:01 +00003864static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003865posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003866{
Barry Warsaw53699e91996-12-10 23:23:01 +00003867 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003868}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003869#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003870
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003871
Guido van Rossumad0ee831995-03-01 10:34:45 +00003872#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003873PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003874"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003875Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003876
Barry Warsaw53699e91996-12-10 23:23:01 +00003877static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003878posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003879{
Barry Warsaw53699e91996-12-10 23:23:01 +00003880 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003881}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003882#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003883
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003884
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003885PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003886"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003887Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003888
Barry Warsaw53699e91996-12-10 23:23:01 +00003889static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003890posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003891{
Barry Warsaw53699e91996-12-10 23:23:01 +00003892 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003893}
3894
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003895
Fred Drakec9680921999-12-13 16:37:25 +00003896#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003897PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003898"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003899Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003900
3901static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003902posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003903{
3904 PyObject *result = NULL;
3905
Fred Drakec9680921999-12-13 16:37:25 +00003906#ifdef NGROUPS_MAX
3907#define MAX_GROUPS NGROUPS_MAX
3908#else
3909 /* defined to be 16 on Solaris7, so this should be a small number */
3910#define MAX_GROUPS 64
3911#endif
3912 gid_t grouplist[MAX_GROUPS];
3913 int n;
3914
3915 n = getgroups(MAX_GROUPS, grouplist);
3916 if (n < 0)
3917 posix_error();
3918 else {
3919 result = PyList_New(n);
3920 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003921 int i;
3922 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003923 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003924 if (o == NULL) {
3925 Py_DECREF(result);
3926 result = NULL;
3927 break;
3928 }
3929 PyList_SET_ITEM(result, i, o);
3930 }
3931 }
3932 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003933
Fred Drakec9680921999-12-13 16:37:25 +00003934 return result;
3935}
3936#endif
3937
Martin v. Löwis606edc12002-06-13 21:09:11 +00003938#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003939PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003940"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003941Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003942
3943static PyObject *
3944posix_getpgid(PyObject *self, PyObject *args)
3945{
3946 int pid, pgid;
3947 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3948 return NULL;
3949 pgid = getpgid(pid);
3950 if (pgid < 0)
3951 return posix_error();
3952 return PyInt_FromLong((long)pgid);
3953}
3954#endif /* HAVE_GETPGID */
3955
3956
Guido van Rossumb6775db1994-08-01 11:34:53 +00003957#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003958PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003959"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003960Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003961
Barry Warsaw53699e91996-12-10 23:23:01 +00003962static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003963posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003964{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003965#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003966 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003967#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003968 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003969#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003970}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003971#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003972
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003973
Guido van Rossumb6775db1994-08-01 11:34:53 +00003974#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003975PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003976"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003977Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003978
Barry Warsaw53699e91996-12-10 23:23:01 +00003979static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003980posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003981{
Guido van Rossum64933891994-10-20 21:56:42 +00003982#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003983 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003984#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003985 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003986#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003987 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003988 Py_INCREF(Py_None);
3989 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003990}
3991
Guido van Rossumb6775db1994-08-01 11:34:53 +00003992#endif /* HAVE_SETPGRP */
3993
Guido van Rossumad0ee831995-03-01 10:34:45 +00003994#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003995PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003996"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003997Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003998
Barry Warsaw53699e91996-12-10 23:23:01 +00003999static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004000posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004001{
Christian Heimesd491d712008-02-01 18:49:26 +00004002 return PyInt_FromLong(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004003}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004004#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004006
Fred Drake12c6e2d1999-12-14 21:25:03 +00004007#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004008PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004009"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004010Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004011
4012static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004013posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004014{
Neal Norwitze241ce82003-02-17 18:17:05 +00004015 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00004016 char *name;
4017 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004018
Fred Drakea30680b2000-12-06 21:24:28 +00004019 errno = 0;
4020 name = getlogin();
4021 if (name == NULL) {
4022 if (errno)
4023 posix_error();
4024 else
4025 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00004026 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00004027 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00004028 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004029 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00004030 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004031
Fred Drake12c6e2d1999-12-14 21:25:03 +00004032 return result;
4033}
4034#endif
4035
Guido van Rossumad0ee831995-03-01 10:34:45 +00004036#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004037PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004038"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004039Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004040
Barry Warsaw53699e91996-12-10 23:23:01 +00004041static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004042posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004043{
Barry Warsaw53699e91996-12-10 23:23:01 +00004044 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004045}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004046#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004048
Guido van Rossumad0ee831995-03-01 10:34:45 +00004049#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004050PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004051"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004052Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004053
Barry Warsaw53699e91996-12-10 23:23:01 +00004054static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004055posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004056{
Christian Heimesd491d712008-02-01 18:49:26 +00004057 pid_t pid;
4058 int sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004059 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00004060 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004061#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004062 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4063 APIRET rc;
4064 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004065 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004066
4067 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4068 APIRET rc;
4069 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004070 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004071
4072 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004073 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004074#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00004075 if (kill(pid, sig) == -1)
4076 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004077#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004078 Py_INCREF(Py_None);
4079 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004080}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004081#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004082
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004083#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004084PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004085"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004086Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004087
4088static PyObject *
4089posix_killpg(PyObject *self, PyObject *args)
4090{
4091 int pgid, sig;
4092 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
4093 return NULL;
4094 if (killpg(pgid, sig) == -1)
4095 return posix_error();
4096 Py_INCREF(Py_None);
4097 return Py_None;
4098}
4099#endif
4100
Guido van Rossumc0125471996-06-28 18:55:32 +00004101#ifdef HAVE_PLOCK
4102
4103#ifdef HAVE_SYS_LOCK_H
4104#include <sys/lock.h>
4105#endif
4106
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004107PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004108"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004109Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004110
Barry Warsaw53699e91996-12-10 23:23:01 +00004111static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004112posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004113{
4114 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004115 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004116 return NULL;
4117 if (plock(op) == -1)
4118 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004119 Py_INCREF(Py_None);
4120 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004121}
4122#endif
4123
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004124
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004125#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004126PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004127"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004128Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004129
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004130#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004131#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004132static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004133async_system(const char *command)
4134{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004135 char errormsg[256], args[1024];
4136 RESULTCODES rcodes;
4137 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004138
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004139 char *shell = getenv("COMSPEC");
4140 if (!shell)
4141 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004142
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004143 /* avoid overflowing the argument buffer */
4144 if (strlen(shell) + 3 + strlen(command) >= 1024)
4145 return ERROR_NOT_ENOUGH_MEMORY
4146
4147 args[0] = '\0';
4148 strcat(args, shell);
4149 strcat(args, "/c ");
4150 strcat(args, command);
4151
4152 /* execute asynchronously, inheriting the environment */
4153 rc = DosExecPgm(errormsg,
4154 sizeof(errormsg),
4155 EXEC_ASYNC,
4156 args,
4157 NULL,
4158 &rcodes,
4159 shell);
4160 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004161}
4162
Guido van Rossumd48f2521997-12-05 22:19:34 +00004163static FILE *
4164popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004165{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004166 int oldfd, tgtfd;
4167 HFILE pipeh[2];
4168 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004169
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004170 /* mode determines which of stdin or stdout is reconnected to
4171 * the pipe to the child
4172 */
4173 if (strchr(mode, 'r') != NULL) {
4174 tgt_fd = 1; /* stdout */
4175 } else if (strchr(mode, 'w')) {
4176 tgt_fd = 0; /* stdin */
4177 } else {
4178 *err = ERROR_INVALID_ACCESS;
4179 return NULL;
4180 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004181
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00004182 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004183 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4184 *err = rc;
4185 return NULL;
4186 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004187
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004188 /* prevent other threads accessing stdio */
4189 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004190
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004191 /* reconnect stdio and execute child */
4192 oldfd = dup(tgtfd);
4193 close(tgtfd);
4194 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4195 DosClose(pipeh[tgtfd]);
4196 rc = async_system(command);
4197 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004198
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004199 /* restore stdio */
4200 dup2(oldfd, tgtfd);
4201 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004202
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004203 /* allow other threads access to stdio */
4204 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004205
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004206 /* if execution of child was successful return file stream */
4207 if (rc == NO_ERROR)
4208 return fdopen(pipeh[1 - tgtfd], mode);
4209 else {
4210 DosClose(pipeh[1 - tgtfd]);
4211 *err = rc;
4212 return NULL;
4213 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004214}
4215
4216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004217posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004218{
4219 char *name;
4220 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00004221 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004222 FILE *fp;
4223 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004224 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004225 return NULL;
4226 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00004227 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004228 Py_END_ALLOW_THREADS
4229 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004230 return os2_error(err);
4231
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004232 f = PyFile_FromFile(fp, name, mode, fclose);
4233 if (f != NULL)
4234 PyFile_SetBufSize(f, bufsize);
4235 return f;
4236}
4237
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004238#elif defined(PYCC_GCC)
4239
4240/* standard posix version of popen() support */
4241static PyObject *
4242posix_popen(PyObject *self, PyObject *args)
4243{
4244 char *name;
4245 char *mode = "r";
4246 int bufsize = -1;
4247 FILE *fp;
4248 PyObject *f;
4249 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4250 return NULL;
4251 Py_BEGIN_ALLOW_THREADS
4252 fp = popen(name, mode);
4253 Py_END_ALLOW_THREADS
4254 if (fp == NULL)
4255 return posix_error();
4256 f = PyFile_FromFile(fp, name, mode, pclose);
4257 if (f != NULL)
4258 PyFile_SetBufSize(f, bufsize);
4259 return f;
4260}
4261
4262/* fork() under OS/2 has lots'o'warts
4263 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4264 * most of this code is a ripoff of the win32 code, but using the
4265 * capabilities of EMX's C library routines
4266 */
4267
4268/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4269#define POPEN_1 1
4270#define POPEN_2 2
4271#define POPEN_3 3
4272#define POPEN_4 4
4273
4274static PyObject *_PyPopen(char *, int, int, int);
4275static int _PyPclose(FILE *file);
4276
4277/*
4278 * Internal dictionary mapping popen* file pointers to process handles,
4279 * for use when retrieving the process exit code. See _PyPclose() below
4280 * for more information on this dictionary's use.
4281 */
4282static PyObject *_PyPopenProcs = NULL;
4283
4284/* os2emx version of popen2()
4285 *
4286 * The result of this function is a pipe (file) connected to the
4287 * process's stdin, and a pipe connected to the process's stdout.
4288 */
4289
4290static PyObject *
4291os2emx_popen2(PyObject *self, PyObject *args)
4292{
4293 PyObject *f;
4294 int tm=0;
4295
4296 char *cmdstring;
4297 char *mode = "t";
4298 int bufsize = -1;
4299 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4300 return NULL;
4301
4302 if (*mode == 't')
4303 tm = O_TEXT;
4304 else if (*mode != 'b') {
4305 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4306 return NULL;
4307 } else
4308 tm = O_BINARY;
4309
4310 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4311
4312 return f;
4313}
4314
4315/*
4316 * Variation on os2emx.popen2
4317 *
4318 * The result of this function is 3 pipes - the process's stdin,
4319 * stdout and stderr
4320 */
4321
4322static PyObject *
4323os2emx_popen3(PyObject *self, PyObject *args)
4324{
4325 PyObject *f;
4326 int tm = 0;
4327
4328 char *cmdstring;
4329 char *mode = "t";
4330 int bufsize = -1;
4331 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4332 return NULL;
4333
4334 if (*mode == 't')
4335 tm = O_TEXT;
4336 else if (*mode != 'b') {
4337 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4338 return NULL;
4339 } else
4340 tm = O_BINARY;
4341
4342 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4343
4344 return f;
4345}
4346
4347/*
4348 * Variation on os2emx.popen2
4349 *
Tim Peters11b23062003-04-23 02:39:17 +00004350 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004351 * and stdout+stderr combined as a single pipe.
4352 */
4353
4354static PyObject *
4355os2emx_popen4(PyObject *self, PyObject *args)
4356{
4357 PyObject *f;
4358 int tm = 0;
4359
4360 char *cmdstring;
4361 char *mode = "t";
4362 int bufsize = -1;
4363 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4364 return NULL;
4365
4366 if (*mode == 't')
4367 tm = O_TEXT;
4368 else if (*mode != 'b') {
4369 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4370 return NULL;
4371 } else
4372 tm = O_BINARY;
4373
4374 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4375
4376 return f;
4377}
4378
4379/* a couple of structures for convenient handling of multiple
4380 * file handles and pipes
4381 */
4382struct file_ref
4383{
4384 int handle;
4385 int flags;
4386};
4387
4388struct pipe_ref
4389{
4390 int rd;
4391 int wr;
4392};
4393
4394/* The following code is derived from the win32 code */
4395
4396static PyObject *
4397_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4398{
4399 struct file_ref stdio[3];
4400 struct pipe_ref p_fd[3];
4401 FILE *p_s[3];
Christian Heimesd491d712008-02-01 18:49:26 +00004402 int file_count, i, pipe_err;
4403 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004404 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4405 PyObject *f, *p_f[3];
4406
4407 /* file modes for subsequent fdopen's on pipe handles */
4408 if (mode == O_TEXT)
4409 {
4410 rd_mode = "rt";
4411 wr_mode = "wt";
4412 }
4413 else
4414 {
4415 rd_mode = "rb";
4416 wr_mode = "wb";
4417 }
4418
4419 /* prepare shell references */
4420 if ((shell = getenv("EMXSHELL")) == NULL)
4421 if ((shell = getenv("COMSPEC")) == NULL)
4422 {
4423 errno = ENOENT;
4424 return posix_error();
4425 }
4426
4427 sh_name = _getname(shell);
4428 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4429 opt = "/c";
4430 else
4431 opt = "-c";
4432
4433 /* save current stdio fds + their flags, and set not inheritable */
4434 i = pipe_err = 0;
4435 while (pipe_err >= 0 && i < 3)
4436 {
4437 pipe_err = stdio[i].handle = dup(i);
4438 stdio[i].flags = fcntl(i, F_GETFD, 0);
4439 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4440 i++;
4441 }
4442 if (pipe_err < 0)
4443 {
4444 /* didn't get them all saved - clean up and bail out */
4445 int saved_err = errno;
4446 while (i-- > 0)
4447 {
4448 close(stdio[i].handle);
4449 }
4450 errno = saved_err;
4451 return posix_error();
4452 }
4453
4454 /* create pipe ends */
4455 file_count = 2;
4456 if (n == POPEN_3)
4457 file_count = 3;
4458 i = pipe_err = 0;
4459 while ((pipe_err == 0) && (i < file_count))
4460 pipe_err = pipe((int *)&p_fd[i++]);
4461 if (pipe_err < 0)
4462 {
4463 /* didn't get them all made - clean up and bail out */
4464 while (i-- > 0)
4465 {
4466 close(p_fd[i].wr);
4467 close(p_fd[i].rd);
4468 }
4469 errno = EPIPE;
4470 return posix_error();
4471 }
4472
4473 /* change the actual standard IO streams over temporarily,
4474 * making the retained pipe ends non-inheritable
4475 */
4476 pipe_err = 0;
4477
4478 /* - stdin */
4479 if (dup2(p_fd[0].rd, 0) == 0)
4480 {
4481 close(p_fd[0].rd);
4482 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4483 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4484 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4485 {
4486 close(p_fd[0].wr);
4487 pipe_err = -1;
4488 }
4489 }
4490 else
4491 {
4492 pipe_err = -1;
4493 }
4494
4495 /* - stdout */
4496 if (pipe_err == 0)
4497 {
4498 if (dup2(p_fd[1].wr, 1) == 1)
4499 {
4500 close(p_fd[1].wr);
4501 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4502 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4503 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4504 {
4505 close(p_fd[1].rd);
4506 pipe_err = -1;
4507 }
4508 }
4509 else
4510 {
4511 pipe_err = -1;
4512 }
4513 }
4514
4515 /* - stderr, as required */
4516 if (pipe_err == 0)
4517 switch (n)
4518 {
4519 case POPEN_3:
4520 {
4521 if (dup2(p_fd[2].wr, 2) == 2)
4522 {
4523 close(p_fd[2].wr);
4524 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4525 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4526 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4527 {
4528 close(p_fd[2].rd);
4529 pipe_err = -1;
4530 }
4531 }
4532 else
4533 {
4534 pipe_err = -1;
4535 }
4536 break;
4537 }
4538
4539 case POPEN_4:
4540 {
4541 if (dup2(1, 2) != 2)
4542 {
4543 pipe_err = -1;
4544 }
4545 break;
4546 }
4547 }
4548
4549 /* spawn the child process */
4550 if (pipe_err == 0)
4551 {
4552 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4553 if (pipe_pid == -1)
4554 {
4555 pipe_err = -1;
4556 }
4557 else
4558 {
4559 /* save the PID into the FILE structure
4560 * NOTE: this implementation doesn't actually
4561 * take advantage of this, but do it for
4562 * completeness - AIM Apr01
4563 */
4564 for (i = 0; i < file_count; i++)
4565 p_s[i]->_pid = pipe_pid;
4566 }
4567 }
4568
4569 /* reset standard IO to normal */
4570 for (i = 0; i < 3; i++)
4571 {
4572 dup2(stdio[i].handle, i);
4573 fcntl(i, F_SETFD, stdio[i].flags);
4574 close(stdio[i].handle);
4575 }
4576
4577 /* if any remnant problems, clean up and bail out */
4578 if (pipe_err < 0)
4579 {
4580 for (i = 0; i < 3; i++)
4581 {
4582 close(p_fd[i].rd);
4583 close(p_fd[i].wr);
4584 }
4585 errno = EPIPE;
4586 return posix_error_with_filename(cmdstring);
4587 }
4588
4589 /* build tuple of file objects to return */
4590 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4591 PyFile_SetBufSize(p_f[0], bufsize);
4592 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4593 PyFile_SetBufSize(p_f[1], bufsize);
4594 if (n == POPEN_3)
4595 {
4596 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4597 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004598 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004599 }
4600 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004601 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004602
4603 /*
4604 * Insert the files we've created into the process dictionary
4605 * all referencing the list with the process handle and the
4606 * initial number of files (see description below in _PyPclose).
4607 * Since if _PyPclose later tried to wait on a process when all
4608 * handles weren't closed, it could create a deadlock with the
4609 * child, we spend some energy here to try to ensure that we
4610 * either insert all file handles into the dictionary or none
4611 * at all. It's a little clumsy with the various popen modes
4612 * and variable number of files involved.
4613 */
4614 if (!_PyPopenProcs)
4615 {
4616 _PyPopenProcs = PyDict_New();
4617 }
4618
4619 if (_PyPopenProcs)
4620 {
4621 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4622 int ins_rc[3];
4623
4624 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4625 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4626
4627 procObj = PyList_New(2);
4628 pidObj = PyInt_FromLong((long) pipe_pid);
4629 intObj = PyInt_FromLong((long) file_count);
4630
4631 if (procObj && pidObj && intObj)
4632 {
4633 PyList_SetItem(procObj, 0, pidObj);
4634 PyList_SetItem(procObj, 1, intObj);
4635
4636 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4637 if (fileObj[0])
4638 {
4639 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4640 fileObj[0],
4641 procObj);
4642 }
4643 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4644 if (fileObj[1])
4645 {
4646 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4647 fileObj[1],
4648 procObj);
4649 }
4650 if (file_count >= 3)
4651 {
4652 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4653 if (fileObj[2])
4654 {
4655 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4656 fileObj[2],
4657 procObj);
4658 }
4659 }
4660
4661 if (ins_rc[0] < 0 || !fileObj[0] ||
4662 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4663 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4664 {
4665 /* Something failed - remove any dictionary
4666 * entries that did make it.
4667 */
4668 if (!ins_rc[0] && fileObj[0])
4669 {
4670 PyDict_DelItem(_PyPopenProcs,
4671 fileObj[0]);
4672 }
4673 if (!ins_rc[1] && fileObj[1])
4674 {
4675 PyDict_DelItem(_PyPopenProcs,
4676 fileObj[1]);
4677 }
4678 if (!ins_rc[2] && fileObj[2])
4679 {
4680 PyDict_DelItem(_PyPopenProcs,
4681 fileObj[2]);
4682 }
4683 }
4684 }
Tim Peters11b23062003-04-23 02:39:17 +00004685
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004686 /*
4687 * Clean up our localized references for the dictionary keys
4688 * and value since PyDict_SetItem will Py_INCREF any copies
4689 * that got placed in the dictionary.
4690 */
4691 Py_XDECREF(procObj);
4692 Py_XDECREF(fileObj[0]);
4693 Py_XDECREF(fileObj[1]);
4694 Py_XDECREF(fileObj[2]);
4695 }
4696
4697 /* Child is launched. */
4698 return f;
4699}
4700
4701/*
4702 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4703 * exit code for the child process and return as a result of the close.
4704 *
4705 * This function uses the _PyPopenProcs dictionary in order to map the
4706 * input file pointer to information about the process that was
4707 * originally created by the popen* call that created the file pointer.
4708 * The dictionary uses the file pointer as a key (with one entry
4709 * inserted for each file returned by the original popen* call) and a
4710 * single list object as the value for all files from a single call.
4711 * The list object contains the Win32 process handle at [0], and a file
4712 * count at [1], which is initialized to the total number of file
4713 * handles using that list.
4714 *
4715 * This function closes whichever handle it is passed, and decrements
4716 * the file count in the dictionary for the process handle pointed to
4717 * by this file. On the last close (when the file count reaches zero),
4718 * this function will wait for the child process and then return its
4719 * exit code as the result of the close() operation. This permits the
4720 * files to be closed in any order - it is always the close() of the
4721 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004722 *
4723 * NOTE: This function is currently called with the GIL released.
4724 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004725 */
4726
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004727static int _PyPclose(FILE *file)
4728{
4729 int result;
4730 int exit_code;
Christian Heimesd491d712008-02-01 18:49:26 +00004731 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004732 PyObject *procObj, *pidObj, *intObj, *fileObj;
4733 int file_count;
4734#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004735 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004736#endif
4737
4738 /* Close the file handle first, to ensure it can't block the
4739 * child from exiting if it's the last handle.
4740 */
4741 result = fclose(file);
4742
4743#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004744 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004745#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004746 if (_PyPopenProcs)
4747 {
4748 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4749 (procObj = PyDict_GetItem(_PyPopenProcs,
4750 fileObj)) != NULL &&
4751 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4752 (intObj = PyList_GetItem(procObj,1)) != NULL)
4753 {
4754 pipe_pid = (int) PyInt_AsLong(pidObj);
4755 file_count = (int) PyInt_AsLong(intObj);
4756
4757 if (file_count > 1)
4758 {
4759 /* Still other files referencing process */
4760 file_count--;
4761 PyList_SetItem(procObj,1,
4762 PyInt_FromLong((long) file_count));
4763 }
4764 else
4765 {
4766 /* Last file for this process */
4767 if (result != EOF &&
4768 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4769 {
4770 /* extract exit status */
4771 if (WIFEXITED(exit_code))
4772 {
4773 result = WEXITSTATUS(exit_code);
4774 }
4775 else
4776 {
4777 errno = EPIPE;
4778 result = -1;
4779 }
4780 }
4781 else
4782 {
4783 /* Indicate failure - this will cause the file object
4784 * to raise an I/O error and translate the last
4785 * error code from errno. We do have a problem with
4786 * last errors that overlap the normal errno table,
4787 * but that's a consistent problem with the file object.
4788 */
4789 result = -1;
4790 }
4791 }
4792
4793 /* Remove this file pointer from dictionary */
4794 PyDict_DelItem(_PyPopenProcs, fileObj);
4795
4796 if (PyDict_Size(_PyPopenProcs) == 0)
4797 {
4798 Py_DECREF(_PyPopenProcs);
4799 _PyPopenProcs = NULL;
4800 }
4801
4802 } /* if object retrieval ok */
4803
4804 Py_XDECREF(fileObj);
4805 } /* if _PyPopenProcs */
4806
4807#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004808 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004809#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004810 return result;
4811}
4812
4813#endif /* PYCC_??? */
4814
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004815#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004816
4817/*
4818 * Portable 'popen' replacement for Win32.
4819 *
4820 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4821 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004822 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004823 */
4824
4825#include <malloc.h>
4826#include <io.h>
4827#include <fcntl.h>
4828
4829/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4830#define POPEN_1 1
4831#define POPEN_2 2
4832#define POPEN_3 3
4833#define POPEN_4 4
4834
4835static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004836static int _PyPclose(FILE *file);
4837
4838/*
4839 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004840 * for use when retrieving the process exit code. See _PyPclose() below
4841 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004842 */
4843static PyObject *_PyPopenProcs = NULL;
4844
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004845
4846/* popen that works from a GUI.
4847 *
4848 * The result of this function is a pipe (file) connected to the
4849 * processes stdin or stdout, depending on the requested mode.
4850 */
4851
4852static PyObject *
4853posix_popen(PyObject *self, PyObject *args)
4854{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004855 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004856 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004857
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004858 char *cmdstring;
4859 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004860 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004861 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004862 return NULL;
4863
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004864 if (*mode == 'r')
4865 tm = _O_RDONLY;
4866 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004867 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004868 return NULL;
4869 } else
4870 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004871
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004872 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004873 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004874 return NULL;
4875 }
4876
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004877 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004878 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004879 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004880 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004881 else
4882 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4883
4884 return f;
4885}
4886
4887/* Variation on win32pipe.popen
4888 *
4889 * The result of this function is a pipe (file) connected to the
4890 * process's stdin, and a pipe connected to the process's stdout.
4891 */
4892
4893static PyObject *
4894win32_popen2(PyObject *self, PyObject *args)
4895{
4896 PyObject *f;
4897 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004898
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004899 char *cmdstring;
4900 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004901 int bufsize = -1;
4902 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004903 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004904
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004905 if (*mode == 't')
4906 tm = _O_TEXT;
4907 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004908 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004909 return NULL;
4910 } else
4911 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004912
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004913 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004914 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004915 return NULL;
4916 }
4917
4918 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004919
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004920 return f;
4921}
4922
4923/*
4924 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004925 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004926 * The result of this function is 3 pipes - the process's stdin,
4927 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004928 */
4929
4930static PyObject *
4931win32_popen3(PyObject *self, PyObject *args)
4932{
4933 PyObject *f;
4934 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004935
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004936 char *cmdstring;
4937 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004938 int bufsize = -1;
4939 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004940 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004941
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004942 if (*mode == 't')
4943 tm = _O_TEXT;
4944 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004945 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004946 return NULL;
4947 } else
4948 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004949
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004950 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004951 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004952 return NULL;
4953 }
4954
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004955 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004957 return f;
4958}
4959
4960/*
4961 * Variation on win32pipe.popen
4962 *
Tim Peters5aa91602002-01-30 05:46:57 +00004963 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004964 * and stdout+stderr combined as a single pipe.
4965 */
4966
4967static PyObject *
4968win32_popen4(PyObject *self, PyObject *args)
4969{
4970 PyObject *f;
4971 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004972
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004973 char *cmdstring;
4974 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004975 int bufsize = -1;
4976 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004977 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004978
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004979 if (*mode == 't')
4980 tm = _O_TEXT;
4981 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004982 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004983 return NULL;
4984 } else
4985 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004986
4987 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004988 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004989 return NULL;
4990 }
4991
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004992 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004993
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004994 return f;
4995}
4996
Mark Hammond08501372001-01-31 07:30:29 +00004997static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004998_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004999 HANDLE hStdin,
5000 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00005001 HANDLE hStderr,
5002 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005003{
5004 PROCESS_INFORMATION piProcInfo;
5005 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005006 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005007 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00005008 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005009 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005010 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005011
5012 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00005013 char *comshell;
5014
Tim Peters92e4dd82002-10-05 01:47:34 +00005015 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005016 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00005017 /* x < i, so x fits into an integer */
5018 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005019
5020 /* Explicitly check if we are using COMMAND.COM. If we are
5021 * then use the w9xpopen hack.
5022 */
5023 comshell = s1 + x;
5024 while (comshell >= s1 && *comshell != '\\')
5025 --comshell;
5026 ++comshell;
5027
5028 if (GetVersion() < 0x80000000 &&
5029 _stricmp(comshell, "command.com") != 0) {
5030 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005031 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00005032 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005033 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00005034 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005035 }
5036 else {
5037 /*
Tim Peters402d5982001-08-27 06:37:48 +00005038 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5039 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005040 */
Mark Hammond08501372001-01-31 07:30:29 +00005041 char modulepath[_MAX_PATH];
5042 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005043 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00005044 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005045 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005046 x = i+1;
5047 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00005048 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00005049 strncat(modulepath,
5050 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00005051 (sizeof(modulepath)/sizeof(modulepath[0]))
5052 -strlen(modulepath));
5053 if (stat(modulepath, &statinfo) != 0) {
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005054 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
Tim Peters5aa91602002-01-30 05:46:57 +00005055 /* Eeek - file-not-found - possibly an embedding
5056 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00005057 */
Tim Peters5aa91602002-01-30 05:46:57 +00005058 strncpy(modulepath,
5059 Py_GetExecPrefix(),
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005060 mplen);
5061 modulepath[mplen-1] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00005062 if (modulepath[strlen(modulepath)-1] != '\\')
5063 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00005064 strncat(modulepath,
5065 szConsoleSpawn,
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005066 mplen-strlen(modulepath));
Mark Hammond08501372001-01-31 07:30:29 +00005067 /* No where else to look - raise an easily identifiable
5068 error, rather than leaving Windows to report
5069 "file not found" - as the user is probably blissfully
5070 unaware this shim EXE is used, and it will confuse them.
5071 (well, it confused me for a while ;-)
5072 */
5073 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00005074 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00005075 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00005076 "for popen to work with your shell "
5077 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00005078 szConsoleSpawn);
5079 return FALSE;
5080 }
5081 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005082 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00005083 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005084 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005085
Tim Peters92e4dd82002-10-05 01:47:34 +00005086 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005087 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005088 /* To maintain correct argument passing semantics,
5089 we pass the command-line as it stands, and allow
5090 quoting to be applied. w9xpopen.exe will then
5091 use its argv vector, and re-quote the necessary
5092 args for the ultimate child process.
5093 */
Tim Peters75cdad52001-11-28 22:07:30 +00005094 PyOS_snprintf(
5095 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005096 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005097 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005098 s1,
5099 s3,
5100 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005101 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00005102 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005103 dialog:
5104 "Your program accessed mem currently in use at xxx"
5105 and a hopeful warning about the stability of your
5106 system.
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00005107 Cost is Ctrl+C won't kill children, but anyone
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005108 who cares can have a go!
5109 */
5110 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005111 }
5112 }
5113
5114 /* Could be an else here to try cmd.exe / command.com in the path
5115 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00005116 else {
Tim Peters402d5982001-08-27 06:37:48 +00005117 PyErr_SetString(PyExc_RuntimeError,
5118 "Cannot locate a COMSPEC environment variable to "
5119 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00005120 return FALSE;
5121 }
Tim Peters5aa91602002-01-30 05:46:57 +00005122
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005123 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5124 siStartInfo.cb = sizeof(STARTUPINFO);
5125 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5126 siStartInfo.hStdInput = hStdin;
5127 siStartInfo.hStdOutput = hStdout;
5128 siStartInfo.hStdError = hStderr;
5129 siStartInfo.wShowWindow = SW_HIDE;
5130
5131 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005132 s2,
5133 NULL,
5134 NULL,
5135 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005136 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005137 NULL,
5138 NULL,
5139 &siStartInfo,
5140 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005141 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005142 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005143
Mark Hammondb37a3732000-08-14 04:47:33 +00005144 /* Return process handle */
5145 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005146 return TRUE;
5147 }
Tim Peters402d5982001-08-27 06:37:48 +00005148 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005149 return FALSE;
5150}
5151
5152/* The following code is based off of KB: Q190351 */
5153
5154static PyObject *
5155_PyPopen(char *cmdstring, int mode, int n)
5156{
5157 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5158 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00005159 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005160
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005161 SECURITY_ATTRIBUTES saAttr;
5162 BOOL fSuccess;
5163 int fd1, fd2, fd3;
5164 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00005165 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005166 PyObject *f;
5167
5168 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5169 saAttr.bInheritHandle = TRUE;
5170 saAttr.lpSecurityDescriptor = NULL;
5171
5172 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5173 return win32_error("CreatePipe", NULL);
5174
5175 /* Create new output read handle and the input write handle. Set
5176 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005177 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005178 * being created. */
5179 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005180 GetCurrentProcess(), &hChildStdinWrDup, 0,
5181 FALSE,
5182 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005183 if (!fSuccess)
5184 return win32_error("DuplicateHandle", NULL);
5185
5186 /* Close the inheritable version of ChildStdin
5187 that we're using. */
5188 CloseHandle(hChildStdinWr);
5189
5190 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5191 return win32_error("CreatePipe", NULL);
5192
5193 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005194 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5195 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005196 if (!fSuccess)
5197 return win32_error("DuplicateHandle", NULL);
5198
5199 /* Close the inheritable version of ChildStdout
5200 that we're using. */
5201 CloseHandle(hChildStdoutRd);
5202
5203 if (n != POPEN_4) {
5204 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5205 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005206 fSuccess = DuplicateHandle(GetCurrentProcess(),
5207 hChildStderrRd,
5208 GetCurrentProcess(),
5209 &hChildStderrRdDup, 0,
5210 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005211 if (!fSuccess)
5212 return win32_error("DuplicateHandle", NULL);
5213 /* Close the inheritable version of ChildStdErr that we're using. */
5214 CloseHandle(hChildStderrRd);
5215 }
Tim Peters5aa91602002-01-30 05:46:57 +00005216
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005217 switch (n) {
5218 case POPEN_1:
5219 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5220 case _O_WRONLY | _O_TEXT:
5221 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005222 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005223 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005224 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005225 PyFile_SetBufSize(f, 0);
5226 /* We don't care about these pipes anymore, so close them. */
5227 CloseHandle(hChildStdoutRdDup);
5228 CloseHandle(hChildStderrRdDup);
5229 break;
5230
5231 case _O_RDONLY | _O_TEXT:
5232 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005233 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005234 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005235 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005236 PyFile_SetBufSize(f, 0);
5237 /* We don't care about these pipes anymore, so close them. */
5238 CloseHandle(hChildStdinWrDup);
5239 CloseHandle(hChildStderrRdDup);
5240 break;
5241
5242 case _O_RDONLY | _O_BINARY:
5243 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005244 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005245 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005246 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005247 PyFile_SetBufSize(f, 0);
5248 /* We don't care about these pipes anymore, so close them. */
5249 CloseHandle(hChildStdinWrDup);
5250 CloseHandle(hChildStderrRdDup);
5251 break;
5252
5253 case _O_WRONLY | _O_BINARY:
5254 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005255 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005256 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005257 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005258 PyFile_SetBufSize(f, 0);
5259 /* We don't care about these pipes anymore, so close them. */
5260 CloseHandle(hChildStdoutRdDup);
5261 CloseHandle(hChildStderrRdDup);
5262 break;
5263 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005264 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005265 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005266
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005267 case POPEN_2:
5268 case POPEN_4:
5269 {
5270 char *m1, *m2;
5271 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005272
Tim Peters7dca21e2002-08-19 00:42:29 +00005273 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005274 m1 = "r";
5275 m2 = "w";
5276 } else {
5277 m1 = "rb";
5278 m2 = "wb";
5279 }
5280
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005281 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005282 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005283 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005284 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005285 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005286 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005287 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005288 PyFile_SetBufSize(p2, 0);
5289
5290 if (n != 4)
5291 CloseHandle(hChildStderrRdDup);
5292
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005293 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005294 Py_XDECREF(p1);
5295 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005296 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005297 break;
5298 }
Tim Peters5aa91602002-01-30 05:46:57 +00005299
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005300 case POPEN_3:
5301 {
5302 char *m1, *m2;
5303 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005304
Tim Peters7dca21e2002-08-19 00:42:29 +00005305 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005306 m1 = "r";
5307 m2 = "w";
5308 } else {
5309 m1 = "rb";
5310 m2 = "wb";
5311 }
5312
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005313 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005314 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005315 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005316 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005317 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005318 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005319 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005320 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5321 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005322 PyFile_SetBufSize(p1, 0);
5323 PyFile_SetBufSize(p2, 0);
5324 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005325 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005326 Py_XDECREF(p1);
5327 Py_XDECREF(p2);
5328 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005329 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005330 break;
5331 }
5332 }
5333
5334 if (n == POPEN_4) {
5335 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005336 hChildStdinRd,
5337 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005338 hChildStdoutWr,
5339 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005340 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005341 }
5342 else {
5343 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005344 hChildStdinRd,
5345 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005346 hChildStderrWr,
5347 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005348 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005349 }
5350
Mark Hammondb37a3732000-08-14 04:47:33 +00005351 /*
5352 * Insert the files we've created into the process dictionary
5353 * all referencing the list with the process handle and the
5354 * initial number of files (see description below in _PyPclose).
5355 * Since if _PyPclose later tried to wait on a process when all
5356 * handles weren't closed, it could create a deadlock with the
5357 * child, we spend some energy here to try to ensure that we
5358 * either insert all file handles into the dictionary or none
5359 * at all. It's a little clumsy with the various popen modes
5360 * and variable number of files involved.
5361 */
5362 if (!_PyPopenProcs) {
5363 _PyPopenProcs = PyDict_New();
5364 }
5365
5366 if (_PyPopenProcs) {
5367 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5368 int ins_rc[3];
5369
5370 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5371 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5372
5373 procObj = PyList_New(2);
5374 hProcessObj = PyLong_FromVoidPtr(hProcess);
5375 intObj = PyInt_FromLong(file_count);
5376
5377 if (procObj && hProcessObj && intObj) {
5378 PyList_SetItem(procObj,0,hProcessObj);
5379 PyList_SetItem(procObj,1,intObj);
5380
5381 fileObj[0] = PyLong_FromVoidPtr(f1);
5382 if (fileObj[0]) {
5383 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5384 fileObj[0],
5385 procObj);
5386 }
5387 if (file_count >= 2) {
5388 fileObj[1] = PyLong_FromVoidPtr(f2);
5389 if (fileObj[1]) {
5390 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5391 fileObj[1],
5392 procObj);
5393 }
5394 }
5395 if (file_count >= 3) {
5396 fileObj[2] = PyLong_FromVoidPtr(f3);
5397 if (fileObj[2]) {
5398 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5399 fileObj[2],
5400 procObj);
5401 }
5402 }
5403
5404 if (ins_rc[0] < 0 || !fileObj[0] ||
5405 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5406 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5407 /* Something failed - remove any dictionary
5408 * entries that did make it.
5409 */
5410 if (!ins_rc[0] && fileObj[0]) {
5411 PyDict_DelItem(_PyPopenProcs,
5412 fileObj[0]);
5413 }
5414 if (!ins_rc[1] && fileObj[1]) {
5415 PyDict_DelItem(_PyPopenProcs,
5416 fileObj[1]);
5417 }
5418 if (!ins_rc[2] && fileObj[2]) {
5419 PyDict_DelItem(_PyPopenProcs,
5420 fileObj[2]);
5421 }
5422 }
5423 }
Tim Peters5aa91602002-01-30 05:46:57 +00005424
Mark Hammondb37a3732000-08-14 04:47:33 +00005425 /*
5426 * Clean up our localized references for the dictionary keys
5427 * and value since PyDict_SetItem will Py_INCREF any copies
5428 * that got placed in the dictionary.
5429 */
5430 Py_XDECREF(procObj);
5431 Py_XDECREF(fileObj[0]);
5432 Py_XDECREF(fileObj[1]);
5433 Py_XDECREF(fileObj[2]);
5434 }
5435
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005436 /* Child is launched. Close the parents copy of those pipe
5437 * handles that only the child should have open. You need to
5438 * make sure that no handles to the write end of the output pipe
5439 * are maintained in this process or else the pipe will not close
5440 * when the child process exits and the ReadFile will hang. */
5441
5442 if (!CloseHandle(hChildStdinRd))
5443 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005444
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005445 if (!CloseHandle(hChildStdoutWr))
5446 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005447
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005448 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5449 return win32_error("CloseHandle", NULL);
5450
5451 return f;
5452}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005453
5454/*
5455 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5456 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005457 *
5458 * This function uses the _PyPopenProcs dictionary in order to map the
5459 * input file pointer to information about the process that was
5460 * originally created by the popen* call that created the file pointer.
5461 * The dictionary uses the file pointer as a key (with one entry
5462 * inserted for each file returned by the original popen* call) and a
5463 * single list object as the value for all files from a single call.
5464 * The list object contains the Win32 process handle at [0], and a file
5465 * count at [1], which is initialized to the total number of file
5466 * handles using that list.
5467 *
5468 * This function closes whichever handle it is passed, and decrements
5469 * the file count in the dictionary for the process handle pointed to
5470 * by this file. On the last close (when the file count reaches zero),
5471 * this function will wait for the child process and then return its
5472 * exit code as the result of the close() operation. This permits the
5473 * files to be closed in any order - it is always the close() of the
5474 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005475 *
5476 * NOTE: This function is currently called with the GIL released.
5477 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005478 */
Tim Peters736aa322000-09-01 06:51:24 +00005479
Fredrik Lundh56055a42000-07-23 19:47:12 +00005480static int _PyPclose(FILE *file)
5481{
Fredrik Lundh20318932000-07-26 17:29:12 +00005482 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005483 DWORD exit_code;
5484 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005485 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5486 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005487#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005488 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005489#endif
5490
Fredrik Lundh20318932000-07-26 17:29:12 +00005491 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005492 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005493 */
5494 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005495#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005496 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005497#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005498 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005499 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5500 (procObj = PyDict_GetItem(_PyPopenProcs,
5501 fileObj)) != NULL &&
5502 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5503 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5504
5505 hProcess = PyLong_AsVoidPtr(hProcessObj);
5506 file_count = PyInt_AsLong(intObj);
5507
5508 if (file_count > 1) {
5509 /* Still other files referencing process */
5510 file_count--;
5511 PyList_SetItem(procObj,1,
5512 PyInt_FromLong(file_count));
5513 } else {
5514 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005515 if (result != EOF &&
5516 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5517 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005518 /* Possible truncation here in 16-bit environments, but
5519 * real exit codes are just the lower byte in any event.
5520 */
5521 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005522 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005523 /* Indicate failure - this will cause the file object
5524 * to raise an I/O error and translate the last Win32
5525 * error code from errno. We do have a problem with
5526 * last errors that overlap the normal errno table,
5527 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005528 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005529 if (result != EOF) {
5530 /* If the error wasn't from the fclose(), then
5531 * set errno for the file object error handling.
5532 */
5533 errno = GetLastError();
5534 }
5535 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005536 }
5537
5538 /* Free up the native handle at this point */
5539 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005540 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005541
Mark Hammondb37a3732000-08-14 04:47:33 +00005542 /* Remove this file pointer from dictionary */
5543 PyDict_DelItem(_PyPopenProcs, fileObj);
5544
5545 if (PyDict_Size(_PyPopenProcs) == 0) {
5546 Py_DECREF(_PyPopenProcs);
5547 _PyPopenProcs = NULL;
5548 }
5549
5550 } /* if object retrieval ok */
5551
5552 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005553 } /* if _PyPopenProcs */
5554
Tim Peters736aa322000-09-01 06:51:24 +00005555#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005556 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005557#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005558 return result;
5559}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005560
5561#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005562static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005563posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005564{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005565 char *name;
5566 char *mode = "r";
5567 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005568 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005569 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005570 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005571 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005572 /* Strip mode of binary or text modifiers */
5573 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5574 mode = "r";
5575 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5576 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005577 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005578 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005579 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005580 if (fp == NULL)
5581 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005582 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005583 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005584 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005585 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005586}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005587
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005588#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005589#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005590
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005591
Guido van Rossumb6775db1994-08-01 11:34:53 +00005592#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005593PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005594"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005595Set the current process's user id.");
5596
Barry Warsaw53699e91996-12-10 23:23:01 +00005597static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005598posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005599{
5600 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005601 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005602 return NULL;
5603 if (setuid(uid) < 0)
5604 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005605 Py_INCREF(Py_None);
5606 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005607}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005608#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005610
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005611#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005612PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005613"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005614Set the current process's effective user id.");
5615
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005616static PyObject *
5617posix_seteuid (PyObject *self, PyObject *args)
5618{
5619 int euid;
5620 if (!PyArg_ParseTuple(args, "i", &euid)) {
5621 return NULL;
5622 } else if (seteuid(euid) < 0) {
5623 return posix_error();
5624 } else {
5625 Py_INCREF(Py_None);
5626 return Py_None;
5627 }
5628}
5629#endif /* HAVE_SETEUID */
5630
5631#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005632PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005633"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005634Set the current process's effective group id.");
5635
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005636static PyObject *
5637posix_setegid (PyObject *self, PyObject *args)
5638{
5639 int egid;
5640 if (!PyArg_ParseTuple(args, "i", &egid)) {
5641 return NULL;
5642 } else if (setegid(egid) < 0) {
5643 return posix_error();
5644 } else {
5645 Py_INCREF(Py_None);
5646 return Py_None;
5647 }
5648}
5649#endif /* HAVE_SETEGID */
5650
5651#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005652PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005653"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005654Set the current process's real and effective user ids.");
5655
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005656static PyObject *
5657posix_setreuid (PyObject *self, PyObject *args)
5658{
5659 int ruid, euid;
5660 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5661 return NULL;
5662 } else if (setreuid(ruid, euid) < 0) {
5663 return posix_error();
5664 } else {
5665 Py_INCREF(Py_None);
5666 return Py_None;
5667 }
5668}
5669#endif /* HAVE_SETREUID */
5670
5671#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005672PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005673"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005674Set the current process's real and effective group ids.");
5675
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005676static PyObject *
5677posix_setregid (PyObject *self, PyObject *args)
5678{
5679 int rgid, egid;
5680 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5681 return NULL;
5682 } else if (setregid(rgid, egid) < 0) {
5683 return posix_error();
5684 } else {
5685 Py_INCREF(Py_None);
5686 return Py_None;
5687 }
5688}
5689#endif /* HAVE_SETREGID */
5690
Guido van Rossumb6775db1994-08-01 11:34:53 +00005691#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005692PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005693"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005694Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005695
Barry Warsaw53699e91996-12-10 23:23:01 +00005696static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005697posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005698{
5699 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005700 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005701 return NULL;
5702 if (setgid(gid) < 0)
5703 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005704 Py_INCREF(Py_None);
5705 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005706}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005707#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005708
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005709#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005710PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005711"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005712Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005713
5714static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005715posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005716{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005717 int i, len;
5718 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005719
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005720 if (!PySequence_Check(groups)) {
5721 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5722 return NULL;
5723 }
5724 len = PySequence_Size(groups);
5725 if (len > MAX_GROUPS) {
5726 PyErr_SetString(PyExc_ValueError, "too many groups");
5727 return NULL;
5728 }
5729 for(i = 0; i < len; i++) {
5730 PyObject *elem;
5731 elem = PySequence_GetItem(groups, i);
5732 if (!elem)
5733 return NULL;
5734 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005735 if (!PyLong_Check(elem)) {
5736 PyErr_SetString(PyExc_TypeError,
5737 "groups must be integers");
5738 Py_DECREF(elem);
5739 return NULL;
5740 } else {
5741 unsigned long x = PyLong_AsUnsignedLong(elem);
5742 if (PyErr_Occurred()) {
5743 PyErr_SetString(PyExc_TypeError,
5744 "group id too big");
5745 Py_DECREF(elem);
5746 return NULL;
5747 }
5748 grouplist[i] = x;
5749 /* read back the value to see if it fitted in gid_t */
5750 if (grouplist[i] != x) {
5751 PyErr_SetString(PyExc_TypeError,
5752 "group id too big");
5753 Py_DECREF(elem);
5754 return NULL;
5755 }
5756 }
5757 } else {
5758 long x = PyInt_AsLong(elem);
5759 grouplist[i] = x;
5760 if (grouplist[i] != x) {
5761 PyErr_SetString(PyExc_TypeError,
5762 "group id too big");
5763 Py_DECREF(elem);
5764 return NULL;
5765 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005766 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005767 Py_DECREF(elem);
5768 }
5769
5770 if (setgroups(len, grouplist) < 0)
5771 return posix_error();
5772 Py_INCREF(Py_None);
5773 return Py_None;
5774}
5775#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005776
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005777#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005778static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005779wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005780{
5781 PyObject *result;
5782 static PyObject *struct_rusage;
5783
5784 if (pid == -1)
5785 return posix_error();
5786
5787 if (struct_rusage == NULL) {
Christian Heimes000a0742008-01-03 22:16:32 +00005788 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Neal Norwitz05a45592006-03-20 06:30:08 +00005789 if (m == NULL)
5790 return NULL;
5791 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5792 Py_DECREF(m);
5793 if (struct_rusage == NULL)
5794 return NULL;
5795 }
5796
5797 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5798 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5799 if (!result)
5800 return NULL;
5801
5802#ifndef doubletime
5803#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5804#endif
5805
5806 PyStructSequence_SET_ITEM(result, 0,
5807 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5808 PyStructSequence_SET_ITEM(result, 1,
5809 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5810#define SET_INT(result, index, value)\
5811 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5812 SET_INT(result, 2, ru->ru_maxrss);
5813 SET_INT(result, 3, ru->ru_ixrss);
5814 SET_INT(result, 4, ru->ru_idrss);
5815 SET_INT(result, 5, ru->ru_isrss);
5816 SET_INT(result, 6, ru->ru_minflt);
5817 SET_INT(result, 7, ru->ru_majflt);
5818 SET_INT(result, 8, ru->ru_nswap);
5819 SET_INT(result, 9, ru->ru_inblock);
5820 SET_INT(result, 10, ru->ru_oublock);
5821 SET_INT(result, 11, ru->ru_msgsnd);
5822 SET_INT(result, 12, ru->ru_msgrcv);
5823 SET_INT(result, 13, ru->ru_nsignals);
5824 SET_INT(result, 14, ru->ru_nvcsw);
5825 SET_INT(result, 15, ru->ru_nivcsw);
5826#undef SET_INT
5827
5828 if (PyErr_Occurred()) {
5829 Py_DECREF(result);
5830 return NULL;
5831 }
5832
Neal Norwitz9b00a562006-03-20 08:47:12 +00005833 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005834}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005835#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005836
5837#ifdef HAVE_WAIT3
5838PyDoc_STRVAR(posix_wait3__doc__,
5839"wait3(options) -> (pid, status, rusage)\n\n\
5840Wait for completion of a child process.");
5841
5842static PyObject *
5843posix_wait3(PyObject *self, PyObject *args)
5844{
Christian Heimesd491d712008-02-01 18:49:26 +00005845 pid_t pid;
5846 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005847 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005848 WAIT_TYPE status;
5849 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005850
5851 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5852 return NULL;
5853
5854 Py_BEGIN_ALLOW_THREADS
5855 pid = wait3(&status, options, &ru);
5856 Py_END_ALLOW_THREADS
5857
Neal Norwitzd5a37542006-03-20 06:48:34 +00005858 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005859}
5860#endif /* HAVE_WAIT3 */
5861
5862#ifdef HAVE_WAIT4
5863PyDoc_STRVAR(posix_wait4__doc__,
5864"wait4(pid, options) -> (pid, status, rusage)\n\n\
5865Wait for completion of a given child process.");
5866
5867static PyObject *
5868posix_wait4(PyObject *self, PyObject *args)
5869{
Christian Heimesd491d712008-02-01 18:49:26 +00005870 pid_t pid;
5871 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005872 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005873 WAIT_TYPE status;
5874 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005875
5876 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5877 return NULL;
5878
5879 Py_BEGIN_ALLOW_THREADS
5880 pid = wait4(pid, &status, options, &ru);
5881 Py_END_ALLOW_THREADS
5882
Neal Norwitzd5a37542006-03-20 06:48:34 +00005883 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005884}
5885#endif /* HAVE_WAIT4 */
5886
Guido van Rossumb6775db1994-08-01 11:34:53 +00005887#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005888PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005889"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005890Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005891
Barry Warsaw53699e91996-12-10 23:23:01 +00005892static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005893posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005894{
Christian Heimesd491d712008-02-01 18:49:26 +00005895 pid_t pid;
5896 int options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005897 WAIT_TYPE status;
5898 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005899
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005900 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005901 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005902 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005903 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005904 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005905 if (pid == -1)
5906 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005907
5908 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005909}
5910
Tim Petersab034fa2002-02-01 11:27:43 +00005911#elif defined(HAVE_CWAIT)
5912
5913/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005914PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005915"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005916"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005917
5918static PyObject *
5919posix_waitpid(PyObject *self, PyObject *args)
5920{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005921 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005922 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005923
5924 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5925 return NULL;
5926 Py_BEGIN_ALLOW_THREADS
5927 pid = _cwait(&status, pid, options);
5928 Py_END_ALLOW_THREADS
5929 if (pid == -1)
5930 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005931
5932 /* shift the status left a byte so this is more like the POSIX waitpid */
5933 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005934}
5935#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005936
Guido van Rossumad0ee831995-03-01 10:34:45 +00005937#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005938PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005939"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005940Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005941
Barry Warsaw53699e91996-12-10 23:23:01 +00005942static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005943posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005944{
Christian Heimesd491d712008-02-01 18:49:26 +00005945 pid_t pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005946 WAIT_TYPE status;
5947 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005948
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005949 Py_BEGIN_ALLOW_THREADS
5950 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005951 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005952 if (pid == -1)
5953 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005954
5955 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005956}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005957#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005958
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005959
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005960PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005961"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005962Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005963
Barry Warsaw53699e91996-12-10 23:23:01 +00005964static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005965posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005966{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005967#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005968 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005969#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005970#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005971 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005972#else
5973 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5974#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005975#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005976}
5977
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005978
Guido van Rossumb6775db1994-08-01 11:34:53 +00005979#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005980PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005981"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005982Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005983
Barry Warsaw53699e91996-12-10 23:23:01 +00005984static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005985posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005986{
Ronald Oussoren10168f22006-10-22 10:45:18 +00005987 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005988 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005989 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005990 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005991#ifdef Py_USING_UNICODE
5992 int arg_is_unicode = 0;
5993#endif
5994
5995 if (!PyArg_ParseTuple(args, "et:readlink",
5996 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005997 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005998#ifdef Py_USING_UNICODE
5999 v = PySequence_GetItem(args, 0);
Neal Norwitz91a57212007-08-12 17:11:13 +00006000 if (v == NULL) {
6001 PyMem_Free(path);
6002 return NULL;
6003 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006004
6005 if (PyUnicode_Check(v)) {
6006 arg_is_unicode = 1;
6007 }
6008 Py_DECREF(v);
6009#endif
6010
Barry Warsaw53699e91996-12-10 23:23:01 +00006011 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00006012 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00006013 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006014 if (n < 0)
Neal Norwitz91a57212007-08-12 17:11:13 +00006015 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006016
Neal Norwitz91a57212007-08-12 17:11:13 +00006017 PyMem_Free(path);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006018 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006019#ifdef Py_USING_UNICODE
6020 if (arg_is_unicode) {
6021 PyObject *w;
6022
6023 w = PyUnicode_FromEncodedObject(v,
6024 Py_FileSystemDefaultEncoding,
6025 "strict");
6026 if (w != NULL) {
6027 Py_DECREF(v);
6028 v = w;
6029 }
6030 else {
6031 /* fall back to the original byte string, as
6032 discussed in patch #683592 */
6033 PyErr_Clear();
6034 }
6035 }
6036#endif
6037 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006038}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006039#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006040
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006041
Guido van Rossumb6775db1994-08-01 11:34:53 +00006042#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006043PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006044"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006045Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006046
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006047static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006048posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006049{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00006050 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006051}
6052#endif /* HAVE_SYMLINK */
6053
6054
6055#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006056#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6057static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006058system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006059{
6060 ULONG value = 0;
6061
6062 Py_BEGIN_ALLOW_THREADS
6063 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6064 Py_END_ALLOW_THREADS
6065
6066 return value;
6067}
6068
6069static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006070posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006071{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006072 /* Currently Only Uptime is Provided -- Others Later */
6073 return Py_BuildValue("ddddd",
6074 (double)0 /* t.tms_utime / HZ */,
6075 (double)0 /* t.tms_stime / HZ */,
6076 (double)0 /* t.tms_cutime / HZ */,
6077 (double)0 /* t.tms_cstime / HZ */,
6078 (double)system_uptime() / 1000);
6079}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006080#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006081#define NEED_TICKS_PER_SECOND
6082static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006083static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006084posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006085{
6086 struct tms t;
6087 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00006088 errno = 0;
6089 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00006090 if (c == (clock_t) -1)
6091 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006092 return Py_BuildValue("ddddd",
Martin v. Löwis03824e42008-12-29 18:17:34 +00006093 (double)t.tms_utime / ticks_per_second,
6094 (double)t.tms_stime / ticks_per_second,
6095 (double)t.tms_cutime / ticks_per_second,
6096 (double)t.tms_cstime / ticks_per_second,
6097 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006098}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006099#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006100#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006101
6102
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006103#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006104#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006105static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006106posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006107{
6108 FILETIME create, exit, kernel, user;
6109 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006110 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006111 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6112 /* The fields of a FILETIME structure are the hi and lo part
6113 of a 64-bit value expressed in 100 nanosecond units.
6114 1e7 is one second in such units; 1e-7 the inverse.
6115 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6116 */
Barry Warsaw53699e91996-12-10 23:23:01 +00006117 return Py_BuildValue(
6118 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006119 (double)(user.dwHighDateTime*429.4967296 +
6120 user.dwLowDateTime*1e-7),
Georg Brandl0a40ffb2008-02-13 07:20:22 +00006121 (double)(kernel.dwHighDateTime*429.4967296 +
6122 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00006123 (double)0,
6124 (double)0,
6125 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006126}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006127#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006128
6129#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006130PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006131"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006132Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006133#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006134
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006135
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006136#ifdef HAVE_GETSID
6137PyDoc_STRVAR(posix_getsid__doc__,
6138"getsid(pid) -> sid\n\n\
6139Call the system call getsid().");
6140
6141static PyObject *
6142posix_getsid(PyObject *self, PyObject *args)
6143{
Christian Heimesd491d712008-02-01 18:49:26 +00006144 pid_t pid;
6145 int sid;
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006146 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
6147 return NULL;
6148 sid = getsid(pid);
6149 if (sid < 0)
6150 return posix_error();
6151 return PyInt_FromLong((long)sid);
6152}
6153#endif /* HAVE_GETSID */
6154
6155
Guido van Rossumb6775db1994-08-01 11:34:53 +00006156#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006157PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006158"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006159Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006160
Barry Warsaw53699e91996-12-10 23:23:01 +00006161static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006162posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006163{
Guido van Rossum687dd131993-05-17 08:34:16 +00006164 if (setsid() < 0)
6165 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006166 Py_INCREF(Py_None);
6167 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006168}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006169#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006170
Guido van Rossumb6775db1994-08-01 11:34:53 +00006171#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006172PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006173"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006174Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006175
Barry Warsaw53699e91996-12-10 23:23:01 +00006176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006177posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006178{
Christian Heimesd491d712008-02-01 18:49:26 +00006179 pid_t pid;
6180 int pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006181 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00006182 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006183 if (setpgid(pid, pgrp) < 0)
6184 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006185 Py_INCREF(Py_None);
6186 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006187}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006188#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006189
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006190
Guido van Rossumb6775db1994-08-01 11:34:53 +00006191#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006192PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006193"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006194Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006195
Barry Warsaw53699e91996-12-10 23:23:01 +00006196static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006197posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006198{
Christian Heimese6a80742008-02-03 19:51:13 +00006199 int fd;
6200 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006201 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006202 return NULL;
6203 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006204 if (pgid < 0)
6205 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006206 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006207}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006208#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006209
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006210
Guido van Rossumb6775db1994-08-01 11:34:53 +00006211#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006212PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006213"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006214Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006215
Barry Warsaw53699e91996-12-10 23:23:01 +00006216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006217posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006218{
6219 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006220 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006221 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006222 if (tcsetpgrp(fd, pgid) < 0)
6223 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00006224 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00006225 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006226}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006227#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006228
Guido van Rossum687dd131993-05-17 08:34:16 +00006229/* Functions acting on file descriptors */
6230
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006231PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006232"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006233Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006234
Barry Warsaw53699e91996-12-10 23:23:01 +00006235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006236posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006237{
Mark Hammondef8b6542001-05-13 08:04:26 +00006238 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006239 int flag;
6240 int mode = 0777;
6241 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006242
6243#ifdef MS_WINDOWS
6244 if (unicode_file_names()) {
6245 PyUnicodeObject *po;
6246 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6247 Py_BEGIN_ALLOW_THREADS
6248 /* PyUnicode_AS_UNICODE OK without thread
6249 lock as it is a simple dereference. */
6250 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6251 Py_END_ALLOW_THREADS
6252 if (fd < 0)
6253 return posix_error();
6254 return PyInt_FromLong((long)fd);
6255 }
6256 /* Drop the argument parsing error as narrow strings
6257 are also valid. */
6258 PyErr_Clear();
6259 }
6260#endif
6261
Tim Peters5aa91602002-01-30 05:46:57 +00006262 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006263 Py_FileSystemDefaultEncoding, &file,
6264 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006265 return NULL;
6266
Barry Warsaw53699e91996-12-10 23:23:01 +00006267 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006268 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006269 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006270 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006271 return posix_error_with_allocated_filename(file);
6272 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006273 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006274}
6275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006276
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006277PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006278"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006279Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006280
Barry Warsaw53699e91996-12-10 23:23:01 +00006281static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006282posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006283{
6284 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006285 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006286 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006287 if (!_PyVerify_fd(fd))
6288 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006289 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006290 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006291 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006292 if (res < 0)
6293 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006294 Py_INCREF(Py_None);
6295 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006296}
6297
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006298
Georg Brandl309501a2008-01-19 20:22:13 +00006299PyDoc_STRVAR(posix_closerange__doc__,
6300"closerange(fd_low, fd_high)\n\n\
6301Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6302
6303static PyObject *
6304posix_closerange(PyObject *self, PyObject *args)
6305{
6306 int fd_from, fd_to, i;
6307 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6308 return NULL;
6309 Py_BEGIN_ALLOW_THREADS
6310 for (i = fd_from; i < fd_to; i++)
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006311 if (_PyVerify_fd(i))
6312 close(i);
Georg Brandl309501a2008-01-19 20:22:13 +00006313 Py_END_ALLOW_THREADS
6314 Py_RETURN_NONE;
6315}
6316
6317
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006318PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006319"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006320Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006321
Barry Warsaw53699e91996-12-10 23:23:01 +00006322static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006323posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006324{
6325 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006326 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006327 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006328 if (!_PyVerify_fd(fd))
6329 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006330 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006331 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006332 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006333 if (fd < 0)
6334 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006335 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006336}
6337
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006338
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006339PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006340"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006341Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006342
Barry Warsaw53699e91996-12-10 23:23:01 +00006343static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006344posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006345{
6346 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006347 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006348 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006349 if (!_PyVerify_fd_dup2(fd, fd2))
6350 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006351 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006352 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006353 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006354 if (res < 0)
6355 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006356 Py_INCREF(Py_None);
6357 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006358}
6359
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006360
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006361PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006362"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006363Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006364
Barry Warsaw53699e91996-12-10 23:23:01 +00006365static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006366posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006367{
6368 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006369#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006370 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006371#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006372 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006373#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006374 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006375 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006376 return NULL;
6377#ifdef SEEK_SET
6378 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6379 switch (how) {
6380 case 0: how = SEEK_SET; break;
6381 case 1: how = SEEK_CUR; break;
6382 case 2: how = SEEK_END; break;
6383 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006384#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006385
6386#if !defined(HAVE_LARGEFILE_SUPPORT)
6387 pos = PyInt_AsLong(posobj);
6388#else
6389 pos = PyLong_Check(posobj) ?
6390 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6391#endif
6392 if (PyErr_Occurred())
6393 return NULL;
6394
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006395 if (!_PyVerify_fd(fd))
6396 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006397 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006398#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006399 res = _lseeki64(fd, pos, how);
6400#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006401 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006402#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006403 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006404 if (res < 0)
6405 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006406
6407#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006408 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006409#else
6410 return PyLong_FromLongLong(res);
6411#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006412}
6413
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006414
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006415PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006416"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006417Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006418
Barry Warsaw53699e91996-12-10 23:23:01 +00006419static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006420posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006421{
Guido van Rossum8bac5461996-06-11 18:38:48 +00006422 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006423 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006424 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006425 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006426 if (size < 0) {
6427 errno = EINVAL;
6428 return posix_error();
6429 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006430 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006431 if (buffer == NULL)
6432 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006433 if (!_PyVerify_fd(fd))
6434 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006435 Py_BEGIN_ALLOW_THREADS
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006436 n = read(fd, PyString_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006437 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006438 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006439 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006440 return posix_error();
6441 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006442 if (n != size)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006443 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006444 return buffer;
6445}
6446
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006447
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006448PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006449"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006450Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006451
Barry Warsaw53699e91996-12-10 23:23:01 +00006452static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006453posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006454{
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006455 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006456 int fd;
6457 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006458
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006459 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00006460 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006461 if (!_PyVerify_fd(fd))
6462 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006463 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006464 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00006465 Py_END_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006466 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00006467 if (size < 0)
6468 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006469 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006470}
6471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006472
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006473PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006474"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006475Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006476
Barry Warsaw53699e91996-12-10 23:23:01 +00006477static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006478posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006479{
6480 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006481 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006482 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006483 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006484 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006485#ifdef __VMS
6486 /* on OpenVMS we must ensure that all bytes are written to the file */
6487 fsync(fd);
6488#endif
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006489 if (!_PyVerify_fd(fd))
6490 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006491 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006492 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006493 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006494 if (res != 0) {
6495#ifdef MS_WINDOWS
6496 return win32_error("fstat", NULL);
6497#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006498 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006499#endif
6500 }
Tim Peters5aa91602002-01-30 05:46:57 +00006501
Martin v. Löwis14694662006-02-03 12:54:16 +00006502 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006503}
6504
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006505
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006506PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006507"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006508Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006509
Barry Warsaw53699e91996-12-10 23:23:01 +00006510static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006511posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006512{
Guido van Rossum687dd131993-05-17 08:34:16 +00006513 int fd;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006514 char *orgmode = "r";
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006515 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006516 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006517 PyObject *f;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006518 char *mode;
6519 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006520 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006521
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006522 /* Sanitize mode. See fileobject.c */
6523 mode = PyMem_MALLOC(strlen(orgmode)+3);
6524 if (!mode) {
6525 PyErr_NoMemory();
6526 return NULL;
6527 }
6528 strcpy(mode, orgmode);
6529 if (_PyFile_SanitizeMode(mode)) {
6530 PyMem_FREE(mode);
Thomas Heller1f043e22002-11-07 16:00:59 +00006531 return NULL;
6532 }
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006533 if (!_PyVerify_fd(fd))
6534 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006535 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006536#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006537 if (mode[0] == 'a') {
6538 /* try to make sure the O_APPEND flag is set */
6539 int flags;
6540 flags = fcntl(fd, F_GETFL);
6541 if (flags != -1)
6542 fcntl(fd, F_SETFL, flags | O_APPEND);
6543 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006544 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006545 /* restore old mode if fdopen failed */
6546 fcntl(fd, F_SETFL, flags);
6547 } else {
6548 fp = fdopen(fd, mode);
6549 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006550#else
6551 fp = fdopen(fd, mode);
6552#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006553 Py_END_ALLOW_THREADS
Neal Norwitzd83eb312007-05-02 04:47:55 +00006554 PyMem_FREE(mode);
Guido van Rossum687dd131993-05-17 08:34:16 +00006555 if (fp == NULL)
6556 return posix_error();
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006557 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006558 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006559 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006560 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006561}
6562
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006563PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006564"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006565Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006566connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006567
6568static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006569posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006570{
6571 int fd;
6572 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6573 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006574 if (!_PyVerify_fd(fd))
6575 return PyBool_FromLong(0);
Fred Drake106c1a02002-04-23 15:58:02 +00006576 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006577}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006578
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006579#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006580PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006581"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006582Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006583
Barry Warsaw53699e91996-12-10 23:23:01 +00006584static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006585posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006586{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006587#if defined(PYOS_OS2)
6588 HFILE read, write;
6589 APIRET rc;
6590
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006591 Py_BEGIN_ALLOW_THREADS
6592 rc = DosCreatePipe( &read, &write, 4096);
6593 Py_END_ALLOW_THREADS
6594 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006595 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006596
6597 return Py_BuildValue("(ii)", read, write);
6598#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006599#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006600 int fds[2];
6601 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006602 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006603 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006604 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006605 if (res != 0)
6606 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006607 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006608#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006609 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006610 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006611 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006612 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006613 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006614 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006615 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006616 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006617 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6618 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006619 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006620#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006621#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006622}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006623#endif /* HAVE_PIPE */
6624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006625
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006626#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006627PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006628"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006629Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006630
Barry Warsaw53699e91996-12-10 23:23:01 +00006631static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006632posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006633{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006634 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006635 int mode = 0666;
6636 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006637 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006638 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006639 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006640 res = mkfifo(filename, mode);
6641 Py_END_ALLOW_THREADS
6642 if (res < 0)
6643 return posix_error();
6644 Py_INCREF(Py_None);
6645 return Py_None;
6646}
6647#endif
6648
6649
Neal Norwitz11690112002-07-30 01:08:28 +00006650#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006651PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006652"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006653Create a filesystem node (file, device special file or named pipe)\n\
6654named filename. mode specifies both the permissions to use and the\n\
6655type of node to be created, being combined (bitwise OR) with one of\n\
6656S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006657device defines the newly created device special file (probably using\n\
6658os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006659
6660
6661static PyObject *
6662posix_mknod(PyObject *self, PyObject *args)
6663{
6664 char *filename;
6665 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006666 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006667 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006668 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006669 return NULL;
6670 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006671 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006672 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006673 if (res < 0)
6674 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006675 Py_INCREF(Py_None);
6676 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006677}
6678#endif
6679
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006680#ifdef HAVE_DEVICE_MACROS
6681PyDoc_STRVAR(posix_major__doc__,
6682"major(device) -> major number\n\
6683Extracts a device major number from a raw device number.");
6684
6685static PyObject *
6686posix_major(PyObject *self, PyObject *args)
6687{
6688 int device;
6689 if (!PyArg_ParseTuple(args, "i:major", &device))
6690 return NULL;
6691 return PyInt_FromLong((long)major(device));
6692}
6693
6694PyDoc_STRVAR(posix_minor__doc__,
6695"minor(device) -> minor number\n\
6696Extracts a device minor number from a raw device number.");
6697
6698static PyObject *
6699posix_minor(PyObject *self, PyObject *args)
6700{
6701 int device;
6702 if (!PyArg_ParseTuple(args, "i:minor", &device))
6703 return NULL;
6704 return PyInt_FromLong((long)minor(device));
6705}
6706
6707PyDoc_STRVAR(posix_makedev__doc__,
6708"makedev(major, minor) -> device number\n\
6709Composes a raw device number from the major and minor device numbers.");
6710
6711static PyObject *
6712posix_makedev(PyObject *self, PyObject *args)
6713{
6714 int major, minor;
6715 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6716 return NULL;
6717 return PyInt_FromLong((long)makedev(major, minor));
6718}
6719#endif /* device macros */
6720
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006721
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006722#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006723PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006724"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006725Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006726
Barry Warsaw53699e91996-12-10 23:23:01 +00006727static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006728posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006729{
6730 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006731 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006732 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006733 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006734
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006735 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006736 return NULL;
6737
6738#if !defined(HAVE_LARGEFILE_SUPPORT)
6739 length = PyInt_AsLong(lenobj);
6740#else
6741 length = PyLong_Check(lenobj) ?
6742 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6743#endif
6744 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006745 return NULL;
6746
Barry Warsaw53699e91996-12-10 23:23:01 +00006747 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006748 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006749 Py_END_ALLOW_THREADS
Benjamin Peterson943a6dd2009-01-19 15:51:27 +00006750 if (res < 0)
6751 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006752 Py_INCREF(Py_None);
6753 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006754}
6755#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006756
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006757#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006758PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006759"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006760Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006761
Fred Drake762e2061999-08-26 17:23:54 +00006762/* Save putenv() parameters as values here, so we can collect them when they
6763 * get re-set with another call for the same key. */
6764static PyObject *posix_putenv_garbage;
6765
Tim Peters5aa91602002-01-30 05:46:57 +00006766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006767posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006768{
6769 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006770 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006771 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006772 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006773
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006774 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006775 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006776
6777#if defined(PYOS_OS2)
6778 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6779 APIRET rc;
6780
Guido van Rossumd48f2521997-12-05 22:19:34 +00006781 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6782 if (rc != NO_ERROR)
6783 return os2_error(rc);
6784
6785 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6786 APIRET rc;
6787
Guido van Rossumd48f2521997-12-05 22:19:34 +00006788 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6789 if (rc != NO_ERROR)
6790 return os2_error(rc);
6791 } else {
6792#endif
6793
Fred Drake762e2061999-08-26 17:23:54 +00006794 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006795 len = strlen(s1) + strlen(s2) + 2;
6796 /* len includes space for a trailing \0; the size arg to
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006797 PyString_FromStringAndSize does not count that */
6798 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006799 if (newstr == NULL)
6800 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006801 newenv = PyString_AS_STRING(newstr);
Anthony Baxter64182fe2006-04-11 12:14:09 +00006802 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6803 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006804 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006805 posix_error();
6806 return NULL;
6807 }
Fred Drake762e2061999-08-26 17:23:54 +00006808 /* Install the first arg and newstr in posix_putenv_garbage;
6809 * this will cause previous value to be collected. This has to
6810 * happen after the real putenv() call because the old value
6811 * was still accessible until then. */
6812 if (PyDict_SetItem(posix_putenv_garbage,
6813 PyTuple_GET_ITEM(args, 0), newstr)) {
6814 /* really not much we can do; just leak */
6815 PyErr_Clear();
6816 }
6817 else {
6818 Py_DECREF(newstr);
6819 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006820
6821#if defined(PYOS_OS2)
6822 }
6823#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006824 Py_INCREF(Py_None);
6825 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006826}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006827#endif /* putenv */
6828
Guido van Rossumc524d952001-10-19 01:31:59 +00006829#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006830PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006831"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006832Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006833
6834static PyObject *
6835posix_unsetenv(PyObject *self, PyObject *args)
6836{
6837 char *s1;
6838
6839 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6840 return NULL;
6841
6842 unsetenv(s1);
6843
6844 /* Remove the key from posix_putenv_garbage;
6845 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006846 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006847 * old value was still accessible until then.
6848 */
6849 if (PyDict_DelItem(posix_putenv_garbage,
6850 PyTuple_GET_ITEM(args, 0))) {
6851 /* really not much we can do; just leak */
6852 PyErr_Clear();
6853 }
6854
6855 Py_INCREF(Py_None);
6856 return Py_None;
6857}
6858#endif /* unsetenv */
6859
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006860PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006861"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006862Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006863
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006865posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006866{
6867 int code;
6868 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006869 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006870 return NULL;
6871 message = strerror(code);
6872 if (message == NULL) {
6873 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006874 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006875 return NULL;
6876 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006877 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006878}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006879
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006880
Guido van Rossumc9641791998-08-04 15:26:23 +00006881#ifdef HAVE_SYS_WAIT_H
6882
Fred Drake106c1a02002-04-23 15:58:02 +00006883#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006884PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006885"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006886Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006887
6888static PyObject *
6889posix_WCOREDUMP(PyObject *self, PyObject *args)
6890{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006891 WAIT_TYPE status;
6892 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006893
Neal Norwitzd5a37542006-03-20 06:48:34 +00006894 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006895 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006896
6897 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006898}
6899#endif /* WCOREDUMP */
6900
6901#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006902PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006903"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006904Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006905job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006906
6907static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006908posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006909{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006910 WAIT_TYPE status;
6911 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006912
Neal Norwitzd5a37542006-03-20 06:48:34 +00006913 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006914 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006915
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006916 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006917}
6918#endif /* WIFCONTINUED */
6919
Guido van Rossumc9641791998-08-04 15:26:23 +00006920#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006921PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006922"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006923Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006924
6925static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006926posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006927{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006928 WAIT_TYPE status;
6929 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006930
Neal Norwitzd5a37542006-03-20 06:48:34 +00006931 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006932 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006933
Fred Drake106c1a02002-04-23 15:58:02 +00006934 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006935}
6936#endif /* WIFSTOPPED */
6937
6938#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006939PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006940"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006941Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006942
6943static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006944posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006945{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006946 WAIT_TYPE status;
6947 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006948
Neal Norwitzd5a37542006-03-20 06:48:34 +00006949 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006950 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006951
Fred Drake106c1a02002-04-23 15:58:02 +00006952 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006953}
6954#endif /* WIFSIGNALED */
6955
6956#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006957PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006958"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006959Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006960system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006961
6962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006963posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006964{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006965 WAIT_TYPE status;
6966 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006967
Neal Norwitzd5a37542006-03-20 06:48:34 +00006968 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006969 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006970
Fred Drake106c1a02002-04-23 15:58:02 +00006971 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006972}
6973#endif /* WIFEXITED */
6974
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006975#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006976PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006977"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006978Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006979
6980static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006981posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006982{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006983 WAIT_TYPE status;
6984 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006985
Neal Norwitzd5a37542006-03-20 06:48:34 +00006986 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006987 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006988
Guido van Rossumc9641791998-08-04 15:26:23 +00006989 return Py_BuildValue("i", WEXITSTATUS(status));
6990}
6991#endif /* WEXITSTATUS */
6992
6993#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006994PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006995"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006996Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006997value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006998
6999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007000posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007001{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007002 WAIT_TYPE status;
7003 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007004
Neal Norwitzd5a37542006-03-20 06:48:34 +00007005 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007006 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007007
Guido van Rossumc9641791998-08-04 15:26:23 +00007008 return Py_BuildValue("i", WTERMSIG(status));
7009}
7010#endif /* WTERMSIG */
7011
7012#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007013PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007014"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007015Return the signal that stopped the process that provided\n\
7016the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007017
7018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007019posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007020{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007021 WAIT_TYPE status;
7022 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007023
Neal Norwitzd5a37542006-03-20 06:48:34 +00007024 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007025 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007026
Guido van Rossumc9641791998-08-04 15:26:23 +00007027 return Py_BuildValue("i", WSTOPSIG(status));
7028}
7029#endif /* WSTOPSIG */
7030
7031#endif /* HAVE_SYS_WAIT_H */
7032
7033
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007034#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007035#ifdef _SCO_DS
7036/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7037 needed definitions in sys/statvfs.h */
7038#define _SVID3
7039#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007040#include <sys/statvfs.h>
7041
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007042static PyObject*
7043_pystatvfs_fromstructstatvfs(struct statvfs st) {
7044 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7045 if (v == NULL)
7046 return NULL;
7047
7048#if !defined(HAVE_LARGEFILE_SUPPORT)
7049 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7050 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7051 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7052 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7053 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7054 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7055 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7056 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7057 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7058 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7059#else
7060 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7061 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00007062 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007063 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00007064 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007065 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007066 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007067 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00007068 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007069 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00007070 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007071 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00007072 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007073 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007074 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7075 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7076#endif
7077
7078 return v;
7079}
7080
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007081PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007082"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007083Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007084
7085static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007086posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007087{
7088 int fd, res;
7089 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007090
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007091 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007092 return NULL;
7093 Py_BEGIN_ALLOW_THREADS
7094 res = fstatvfs(fd, &st);
7095 Py_END_ALLOW_THREADS
7096 if (res != 0)
7097 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007098
7099 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007100}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007101#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007102
7103
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007104#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007105#include <sys/statvfs.h>
7106
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007107PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007108"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007109Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007110
7111static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007112posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007113{
7114 char *path;
7115 int res;
7116 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007117 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007118 return NULL;
7119 Py_BEGIN_ALLOW_THREADS
7120 res = statvfs(path, &st);
7121 Py_END_ALLOW_THREADS
7122 if (res != 0)
7123 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007124
7125 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007126}
7127#endif /* HAVE_STATVFS */
7128
7129
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007130#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007131PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007132"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007133Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007134The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007135or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007136
7137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007138posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007139{
7140 PyObject *result = NULL;
7141 char *dir = NULL;
7142 char *pfx = NULL;
7143 char *name;
7144
7145 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7146 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007147
7148 if (PyErr_Warn(PyExc_RuntimeWarning,
7149 "tempnam is a potential security risk to your program") < 0)
7150 return NULL;
7151
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007152#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007153 name = _tempnam(dir, pfx);
7154#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007155 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007156#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007157 if (name == NULL)
7158 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007159 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007160 free(name);
7161 return result;
7162}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007163#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007164
7165
7166#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007167PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007168"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007169Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007170
7171static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007172posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007173{
7174 FILE *fp;
7175
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007176 fp = tmpfile();
7177 if (fp == NULL)
7178 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007179 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007180}
7181#endif
7182
7183
7184#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007185PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007186"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007187Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007188
7189static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007190posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007191{
7192 char buffer[L_tmpnam];
7193 char *name;
7194
Skip Montanaro95618b52001-08-18 18:52:10 +00007195 if (PyErr_Warn(PyExc_RuntimeWarning,
7196 "tmpnam is a potential security risk to your program") < 0)
7197 return NULL;
7198
Greg Wardb48bc172000-03-01 21:51:56 +00007199#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007200 name = tmpnam_r(buffer);
7201#else
7202 name = tmpnam(buffer);
7203#endif
7204 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007205 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007206#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007207 "unexpected NULL from tmpnam_r"
7208#else
7209 "unexpected NULL from tmpnam"
7210#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007211 );
7212 PyErr_SetObject(PyExc_OSError, err);
7213 Py_XDECREF(err);
7214 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007215 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007216 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007217}
7218#endif
7219
7220
Fred Drakec9680921999-12-13 16:37:25 +00007221/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7222 * It maps strings representing configuration variable names to
7223 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007224 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007225 * rarely-used constants. There are three separate tables that use
7226 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007227 *
7228 * This code is always included, even if none of the interfaces that
7229 * need it are included. The #if hackery needed to avoid it would be
7230 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007231 */
7232struct constdef {
7233 char *name;
7234 long value;
7235};
7236
Fred Drake12c6e2d1999-12-14 21:25:03 +00007237static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007238conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7239 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007240{
7241 if (PyInt_Check(arg)) {
7242 *valuep = PyInt_AS_LONG(arg);
7243 return 1;
7244 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007245 if (PyString_Check(arg)) {
Fred Drake12c6e2d1999-12-14 21:25:03 +00007246 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00007247 size_t lo = 0;
7248 size_t mid;
7249 size_t hi = tablesize;
7250 int cmp;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007251 char *confname = PyString_AS_STRING(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007252 while (lo < hi) {
7253 mid = (lo + hi) / 2;
7254 cmp = strcmp(confname, table[mid].name);
7255 if (cmp < 0)
7256 hi = mid;
7257 else if (cmp > 0)
7258 lo = mid + 1;
7259 else {
7260 *valuep = table[mid].value;
7261 return 1;
7262 }
7263 }
7264 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7265 }
7266 else
7267 PyErr_SetString(PyExc_TypeError,
7268 "configuration names must be strings or integers");
7269 return 0;
7270}
7271
7272
7273#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7274static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007275#ifdef _PC_ABI_AIO_XFER_MAX
7276 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7277#endif
7278#ifdef _PC_ABI_ASYNC_IO
7279 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7280#endif
Fred Drakec9680921999-12-13 16:37:25 +00007281#ifdef _PC_ASYNC_IO
7282 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7283#endif
7284#ifdef _PC_CHOWN_RESTRICTED
7285 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7286#endif
7287#ifdef _PC_FILESIZEBITS
7288 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7289#endif
7290#ifdef _PC_LAST
7291 {"PC_LAST", _PC_LAST},
7292#endif
7293#ifdef _PC_LINK_MAX
7294 {"PC_LINK_MAX", _PC_LINK_MAX},
7295#endif
7296#ifdef _PC_MAX_CANON
7297 {"PC_MAX_CANON", _PC_MAX_CANON},
7298#endif
7299#ifdef _PC_MAX_INPUT
7300 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7301#endif
7302#ifdef _PC_NAME_MAX
7303 {"PC_NAME_MAX", _PC_NAME_MAX},
7304#endif
7305#ifdef _PC_NO_TRUNC
7306 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7307#endif
7308#ifdef _PC_PATH_MAX
7309 {"PC_PATH_MAX", _PC_PATH_MAX},
7310#endif
7311#ifdef _PC_PIPE_BUF
7312 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7313#endif
7314#ifdef _PC_PRIO_IO
7315 {"PC_PRIO_IO", _PC_PRIO_IO},
7316#endif
7317#ifdef _PC_SOCK_MAXBUF
7318 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7319#endif
7320#ifdef _PC_SYNC_IO
7321 {"PC_SYNC_IO", _PC_SYNC_IO},
7322#endif
7323#ifdef _PC_VDISABLE
7324 {"PC_VDISABLE", _PC_VDISABLE},
7325#endif
7326};
7327
Fred Drakec9680921999-12-13 16:37:25 +00007328static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007329conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007330{
7331 return conv_confname(arg, valuep, posix_constants_pathconf,
7332 sizeof(posix_constants_pathconf)
7333 / sizeof(struct constdef));
7334}
7335#endif
7336
7337#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007338PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007339"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007340Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007341If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007342
7343static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007344posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007345{
7346 PyObject *result = NULL;
7347 int name, fd;
7348
Fred Drake12c6e2d1999-12-14 21:25:03 +00007349 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7350 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00007351 long limit;
7352
7353 errno = 0;
7354 limit = fpathconf(fd, name);
7355 if (limit == -1 && errno != 0)
7356 posix_error();
7357 else
7358 result = PyInt_FromLong(limit);
7359 }
7360 return result;
7361}
7362#endif
7363
7364
7365#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007366PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007367"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007368Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007369If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007370
7371static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007372posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007373{
7374 PyObject *result = NULL;
7375 int name;
7376 char *path;
7377
7378 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7379 conv_path_confname, &name)) {
7380 long limit;
7381
7382 errno = 0;
7383 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007384 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00007385 if (errno == EINVAL)
7386 /* could be a path or name problem */
7387 posix_error();
7388 else
7389 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007390 }
Fred Drakec9680921999-12-13 16:37:25 +00007391 else
7392 result = PyInt_FromLong(limit);
7393 }
7394 return result;
7395}
7396#endif
7397
7398#ifdef HAVE_CONFSTR
7399static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007400#ifdef _CS_ARCHITECTURE
7401 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7402#endif
7403#ifdef _CS_HOSTNAME
7404 {"CS_HOSTNAME", _CS_HOSTNAME},
7405#endif
7406#ifdef _CS_HW_PROVIDER
7407 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7408#endif
7409#ifdef _CS_HW_SERIAL
7410 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7411#endif
7412#ifdef _CS_INITTAB_NAME
7413 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7414#endif
Fred Drakec9680921999-12-13 16:37:25 +00007415#ifdef _CS_LFS64_CFLAGS
7416 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7417#endif
7418#ifdef _CS_LFS64_LDFLAGS
7419 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7420#endif
7421#ifdef _CS_LFS64_LIBS
7422 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7423#endif
7424#ifdef _CS_LFS64_LINTFLAGS
7425 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7426#endif
7427#ifdef _CS_LFS_CFLAGS
7428 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7429#endif
7430#ifdef _CS_LFS_LDFLAGS
7431 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7432#endif
7433#ifdef _CS_LFS_LIBS
7434 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7435#endif
7436#ifdef _CS_LFS_LINTFLAGS
7437 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7438#endif
Fred Draked86ed291999-12-15 15:34:33 +00007439#ifdef _CS_MACHINE
7440 {"CS_MACHINE", _CS_MACHINE},
7441#endif
Fred Drakec9680921999-12-13 16:37:25 +00007442#ifdef _CS_PATH
7443 {"CS_PATH", _CS_PATH},
7444#endif
Fred Draked86ed291999-12-15 15:34:33 +00007445#ifdef _CS_RELEASE
7446 {"CS_RELEASE", _CS_RELEASE},
7447#endif
7448#ifdef _CS_SRPC_DOMAIN
7449 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7450#endif
7451#ifdef _CS_SYSNAME
7452 {"CS_SYSNAME", _CS_SYSNAME},
7453#endif
7454#ifdef _CS_VERSION
7455 {"CS_VERSION", _CS_VERSION},
7456#endif
Fred Drakec9680921999-12-13 16:37:25 +00007457#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7458 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7459#endif
7460#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7461 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7462#endif
7463#ifdef _CS_XBS5_ILP32_OFF32_LIBS
7464 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7465#endif
7466#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7467 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7468#endif
7469#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7470 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7471#endif
7472#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7473 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7474#endif
7475#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7476 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7477#endif
7478#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7479 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7480#endif
7481#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7482 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7483#endif
7484#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7485 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7486#endif
7487#ifdef _CS_XBS5_LP64_OFF64_LIBS
7488 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7489#endif
7490#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7491 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7492#endif
7493#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7494 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7495#endif
7496#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7497 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7498#endif
7499#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7500 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7501#endif
7502#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7503 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7504#endif
Fred Draked86ed291999-12-15 15:34:33 +00007505#ifdef _MIPS_CS_AVAIL_PROCESSORS
7506 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7507#endif
7508#ifdef _MIPS_CS_BASE
7509 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7510#endif
7511#ifdef _MIPS_CS_HOSTID
7512 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7513#endif
7514#ifdef _MIPS_CS_HW_NAME
7515 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7516#endif
7517#ifdef _MIPS_CS_NUM_PROCESSORS
7518 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7519#endif
7520#ifdef _MIPS_CS_OSREL_MAJ
7521 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7522#endif
7523#ifdef _MIPS_CS_OSREL_MIN
7524 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7525#endif
7526#ifdef _MIPS_CS_OSREL_PATCH
7527 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7528#endif
7529#ifdef _MIPS_CS_OS_NAME
7530 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7531#endif
7532#ifdef _MIPS_CS_OS_PROVIDER
7533 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7534#endif
7535#ifdef _MIPS_CS_PROCESSORS
7536 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7537#endif
7538#ifdef _MIPS_CS_SERIAL
7539 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7540#endif
7541#ifdef _MIPS_CS_VENDOR
7542 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7543#endif
Fred Drakec9680921999-12-13 16:37:25 +00007544};
7545
7546static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007547conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007548{
7549 return conv_confname(arg, valuep, posix_constants_confstr,
7550 sizeof(posix_constants_confstr)
7551 / sizeof(struct constdef));
7552}
7553
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007554PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007555"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007556Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007557
7558static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007559posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007560{
7561 PyObject *result = NULL;
7562 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007563 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007564
7565 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007566 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007567
Fred Drakec9680921999-12-13 16:37:25 +00007568 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007569 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007570 if (len == 0) {
7571 if (errno) {
7572 posix_error();
7573 }
7574 else {
7575 result = Py_None;
7576 Py_INCREF(Py_None);
7577 }
Fred Drakec9680921999-12-13 16:37:25 +00007578 }
7579 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007580 if ((unsigned int)len >= sizeof(buffer)) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007581 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007582 if (result != NULL)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007583 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007584 }
7585 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007586 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007587 }
7588 }
7589 return result;
7590}
7591#endif
7592
7593
7594#ifdef HAVE_SYSCONF
7595static struct constdef posix_constants_sysconf[] = {
7596#ifdef _SC_2_CHAR_TERM
7597 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7598#endif
7599#ifdef _SC_2_C_BIND
7600 {"SC_2_C_BIND", _SC_2_C_BIND},
7601#endif
7602#ifdef _SC_2_C_DEV
7603 {"SC_2_C_DEV", _SC_2_C_DEV},
7604#endif
7605#ifdef _SC_2_C_VERSION
7606 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7607#endif
7608#ifdef _SC_2_FORT_DEV
7609 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7610#endif
7611#ifdef _SC_2_FORT_RUN
7612 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7613#endif
7614#ifdef _SC_2_LOCALEDEF
7615 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7616#endif
7617#ifdef _SC_2_SW_DEV
7618 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7619#endif
7620#ifdef _SC_2_UPE
7621 {"SC_2_UPE", _SC_2_UPE},
7622#endif
7623#ifdef _SC_2_VERSION
7624 {"SC_2_VERSION", _SC_2_VERSION},
7625#endif
Fred Draked86ed291999-12-15 15:34:33 +00007626#ifdef _SC_ABI_ASYNCHRONOUS_IO
7627 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7628#endif
7629#ifdef _SC_ACL
7630 {"SC_ACL", _SC_ACL},
7631#endif
Fred Drakec9680921999-12-13 16:37:25 +00007632#ifdef _SC_AIO_LISTIO_MAX
7633 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7634#endif
Fred Drakec9680921999-12-13 16:37:25 +00007635#ifdef _SC_AIO_MAX
7636 {"SC_AIO_MAX", _SC_AIO_MAX},
7637#endif
7638#ifdef _SC_AIO_PRIO_DELTA_MAX
7639 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7640#endif
7641#ifdef _SC_ARG_MAX
7642 {"SC_ARG_MAX", _SC_ARG_MAX},
7643#endif
7644#ifdef _SC_ASYNCHRONOUS_IO
7645 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7646#endif
7647#ifdef _SC_ATEXIT_MAX
7648 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7649#endif
Fred Draked86ed291999-12-15 15:34:33 +00007650#ifdef _SC_AUDIT
7651 {"SC_AUDIT", _SC_AUDIT},
7652#endif
Fred Drakec9680921999-12-13 16:37:25 +00007653#ifdef _SC_AVPHYS_PAGES
7654 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7655#endif
7656#ifdef _SC_BC_BASE_MAX
7657 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7658#endif
7659#ifdef _SC_BC_DIM_MAX
7660 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7661#endif
7662#ifdef _SC_BC_SCALE_MAX
7663 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7664#endif
7665#ifdef _SC_BC_STRING_MAX
7666 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7667#endif
Fred Draked86ed291999-12-15 15:34:33 +00007668#ifdef _SC_CAP
7669 {"SC_CAP", _SC_CAP},
7670#endif
Fred Drakec9680921999-12-13 16:37:25 +00007671#ifdef _SC_CHARCLASS_NAME_MAX
7672 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7673#endif
7674#ifdef _SC_CHAR_BIT
7675 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7676#endif
7677#ifdef _SC_CHAR_MAX
7678 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7679#endif
7680#ifdef _SC_CHAR_MIN
7681 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7682#endif
7683#ifdef _SC_CHILD_MAX
7684 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7685#endif
7686#ifdef _SC_CLK_TCK
7687 {"SC_CLK_TCK", _SC_CLK_TCK},
7688#endif
7689#ifdef _SC_COHER_BLKSZ
7690 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7691#endif
7692#ifdef _SC_COLL_WEIGHTS_MAX
7693 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7694#endif
7695#ifdef _SC_DCACHE_ASSOC
7696 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7697#endif
7698#ifdef _SC_DCACHE_BLKSZ
7699 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7700#endif
7701#ifdef _SC_DCACHE_LINESZ
7702 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7703#endif
7704#ifdef _SC_DCACHE_SZ
7705 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7706#endif
7707#ifdef _SC_DCACHE_TBLKSZ
7708 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7709#endif
7710#ifdef _SC_DELAYTIMER_MAX
7711 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7712#endif
7713#ifdef _SC_EQUIV_CLASS_MAX
7714 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7715#endif
7716#ifdef _SC_EXPR_NEST_MAX
7717 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7718#endif
7719#ifdef _SC_FSYNC
7720 {"SC_FSYNC", _SC_FSYNC},
7721#endif
7722#ifdef _SC_GETGR_R_SIZE_MAX
7723 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7724#endif
7725#ifdef _SC_GETPW_R_SIZE_MAX
7726 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7727#endif
7728#ifdef _SC_ICACHE_ASSOC
7729 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7730#endif
7731#ifdef _SC_ICACHE_BLKSZ
7732 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7733#endif
7734#ifdef _SC_ICACHE_LINESZ
7735 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7736#endif
7737#ifdef _SC_ICACHE_SZ
7738 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7739#endif
Fred Draked86ed291999-12-15 15:34:33 +00007740#ifdef _SC_INF
7741 {"SC_INF", _SC_INF},
7742#endif
Fred Drakec9680921999-12-13 16:37:25 +00007743#ifdef _SC_INT_MAX
7744 {"SC_INT_MAX", _SC_INT_MAX},
7745#endif
7746#ifdef _SC_INT_MIN
7747 {"SC_INT_MIN", _SC_INT_MIN},
7748#endif
7749#ifdef _SC_IOV_MAX
7750 {"SC_IOV_MAX", _SC_IOV_MAX},
7751#endif
Fred Draked86ed291999-12-15 15:34:33 +00007752#ifdef _SC_IP_SECOPTS
7753 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7754#endif
Fred Drakec9680921999-12-13 16:37:25 +00007755#ifdef _SC_JOB_CONTROL
7756 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7757#endif
Fred Draked86ed291999-12-15 15:34:33 +00007758#ifdef _SC_KERN_POINTERS
7759 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7760#endif
7761#ifdef _SC_KERN_SIM
7762 {"SC_KERN_SIM", _SC_KERN_SIM},
7763#endif
Fred Drakec9680921999-12-13 16:37:25 +00007764#ifdef _SC_LINE_MAX
7765 {"SC_LINE_MAX", _SC_LINE_MAX},
7766#endif
7767#ifdef _SC_LOGIN_NAME_MAX
7768 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7769#endif
7770#ifdef _SC_LOGNAME_MAX
7771 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7772#endif
7773#ifdef _SC_LONG_BIT
7774 {"SC_LONG_BIT", _SC_LONG_BIT},
7775#endif
Fred Draked86ed291999-12-15 15:34:33 +00007776#ifdef _SC_MAC
7777 {"SC_MAC", _SC_MAC},
7778#endif
Fred Drakec9680921999-12-13 16:37:25 +00007779#ifdef _SC_MAPPED_FILES
7780 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7781#endif
7782#ifdef _SC_MAXPID
7783 {"SC_MAXPID", _SC_MAXPID},
7784#endif
7785#ifdef _SC_MB_LEN_MAX
7786 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7787#endif
7788#ifdef _SC_MEMLOCK
7789 {"SC_MEMLOCK", _SC_MEMLOCK},
7790#endif
7791#ifdef _SC_MEMLOCK_RANGE
7792 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7793#endif
7794#ifdef _SC_MEMORY_PROTECTION
7795 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7796#endif
7797#ifdef _SC_MESSAGE_PASSING
7798 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7799#endif
Fred Draked86ed291999-12-15 15:34:33 +00007800#ifdef _SC_MMAP_FIXED_ALIGNMENT
7801 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7802#endif
Fred Drakec9680921999-12-13 16:37:25 +00007803#ifdef _SC_MQ_OPEN_MAX
7804 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7805#endif
7806#ifdef _SC_MQ_PRIO_MAX
7807 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7808#endif
Fred Draked86ed291999-12-15 15:34:33 +00007809#ifdef _SC_NACLS_MAX
7810 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7811#endif
Fred Drakec9680921999-12-13 16:37:25 +00007812#ifdef _SC_NGROUPS_MAX
7813 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7814#endif
7815#ifdef _SC_NL_ARGMAX
7816 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7817#endif
7818#ifdef _SC_NL_LANGMAX
7819 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7820#endif
7821#ifdef _SC_NL_MSGMAX
7822 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7823#endif
7824#ifdef _SC_NL_NMAX
7825 {"SC_NL_NMAX", _SC_NL_NMAX},
7826#endif
7827#ifdef _SC_NL_SETMAX
7828 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7829#endif
7830#ifdef _SC_NL_TEXTMAX
7831 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7832#endif
7833#ifdef _SC_NPROCESSORS_CONF
7834 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7835#endif
7836#ifdef _SC_NPROCESSORS_ONLN
7837 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7838#endif
Fred Draked86ed291999-12-15 15:34:33 +00007839#ifdef _SC_NPROC_CONF
7840 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7841#endif
7842#ifdef _SC_NPROC_ONLN
7843 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7844#endif
Fred Drakec9680921999-12-13 16:37:25 +00007845#ifdef _SC_NZERO
7846 {"SC_NZERO", _SC_NZERO},
7847#endif
7848#ifdef _SC_OPEN_MAX
7849 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7850#endif
7851#ifdef _SC_PAGESIZE
7852 {"SC_PAGESIZE", _SC_PAGESIZE},
7853#endif
7854#ifdef _SC_PAGE_SIZE
7855 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7856#endif
7857#ifdef _SC_PASS_MAX
7858 {"SC_PASS_MAX", _SC_PASS_MAX},
7859#endif
7860#ifdef _SC_PHYS_PAGES
7861 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7862#endif
7863#ifdef _SC_PII
7864 {"SC_PII", _SC_PII},
7865#endif
7866#ifdef _SC_PII_INTERNET
7867 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7868#endif
7869#ifdef _SC_PII_INTERNET_DGRAM
7870 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7871#endif
7872#ifdef _SC_PII_INTERNET_STREAM
7873 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7874#endif
7875#ifdef _SC_PII_OSI
7876 {"SC_PII_OSI", _SC_PII_OSI},
7877#endif
7878#ifdef _SC_PII_OSI_CLTS
7879 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7880#endif
7881#ifdef _SC_PII_OSI_COTS
7882 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7883#endif
7884#ifdef _SC_PII_OSI_M
7885 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7886#endif
7887#ifdef _SC_PII_SOCKET
7888 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7889#endif
7890#ifdef _SC_PII_XTI
7891 {"SC_PII_XTI", _SC_PII_XTI},
7892#endif
7893#ifdef _SC_POLL
7894 {"SC_POLL", _SC_POLL},
7895#endif
7896#ifdef _SC_PRIORITIZED_IO
7897 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7898#endif
7899#ifdef _SC_PRIORITY_SCHEDULING
7900 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7901#endif
7902#ifdef _SC_REALTIME_SIGNALS
7903 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7904#endif
7905#ifdef _SC_RE_DUP_MAX
7906 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7907#endif
7908#ifdef _SC_RTSIG_MAX
7909 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7910#endif
7911#ifdef _SC_SAVED_IDS
7912 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7913#endif
7914#ifdef _SC_SCHAR_MAX
7915 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7916#endif
7917#ifdef _SC_SCHAR_MIN
7918 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7919#endif
7920#ifdef _SC_SELECT
7921 {"SC_SELECT", _SC_SELECT},
7922#endif
7923#ifdef _SC_SEMAPHORES
7924 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7925#endif
7926#ifdef _SC_SEM_NSEMS_MAX
7927 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7928#endif
7929#ifdef _SC_SEM_VALUE_MAX
7930 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7931#endif
7932#ifdef _SC_SHARED_MEMORY_OBJECTS
7933 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7934#endif
7935#ifdef _SC_SHRT_MAX
7936 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7937#endif
7938#ifdef _SC_SHRT_MIN
7939 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7940#endif
7941#ifdef _SC_SIGQUEUE_MAX
7942 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7943#endif
7944#ifdef _SC_SIGRT_MAX
7945 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7946#endif
7947#ifdef _SC_SIGRT_MIN
7948 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7949#endif
Fred Draked86ed291999-12-15 15:34:33 +00007950#ifdef _SC_SOFTPOWER
7951 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7952#endif
Fred Drakec9680921999-12-13 16:37:25 +00007953#ifdef _SC_SPLIT_CACHE
7954 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7955#endif
7956#ifdef _SC_SSIZE_MAX
7957 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7958#endif
7959#ifdef _SC_STACK_PROT
7960 {"SC_STACK_PROT", _SC_STACK_PROT},
7961#endif
7962#ifdef _SC_STREAM_MAX
7963 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7964#endif
7965#ifdef _SC_SYNCHRONIZED_IO
7966 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7967#endif
7968#ifdef _SC_THREADS
7969 {"SC_THREADS", _SC_THREADS},
7970#endif
7971#ifdef _SC_THREAD_ATTR_STACKADDR
7972 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7973#endif
7974#ifdef _SC_THREAD_ATTR_STACKSIZE
7975 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7976#endif
7977#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7978 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7979#endif
7980#ifdef _SC_THREAD_KEYS_MAX
7981 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7982#endif
7983#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7984 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7985#endif
7986#ifdef _SC_THREAD_PRIO_INHERIT
7987 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7988#endif
7989#ifdef _SC_THREAD_PRIO_PROTECT
7990 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7991#endif
7992#ifdef _SC_THREAD_PROCESS_SHARED
7993 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7994#endif
7995#ifdef _SC_THREAD_SAFE_FUNCTIONS
7996 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7997#endif
7998#ifdef _SC_THREAD_STACK_MIN
7999 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
8000#endif
8001#ifdef _SC_THREAD_THREADS_MAX
8002 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
8003#endif
8004#ifdef _SC_TIMERS
8005 {"SC_TIMERS", _SC_TIMERS},
8006#endif
8007#ifdef _SC_TIMER_MAX
8008 {"SC_TIMER_MAX", _SC_TIMER_MAX},
8009#endif
8010#ifdef _SC_TTY_NAME_MAX
8011 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
8012#endif
8013#ifdef _SC_TZNAME_MAX
8014 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
8015#endif
8016#ifdef _SC_T_IOV_MAX
8017 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
8018#endif
8019#ifdef _SC_UCHAR_MAX
8020 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
8021#endif
8022#ifdef _SC_UINT_MAX
8023 {"SC_UINT_MAX", _SC_UINT_MAX},
8024#endif
8025#ifdef _SC_UIO_MAXIOV
8026 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
8027#endif
8028#ifdef _SC_ULONG_MAX
8029 {"SC_ULONG_MAX", _SC_ULONG_MAX},
8030#endif
8031#ifdef _SC_USHRT_MAX
8032 {"SC_USHRT_MAX", _SC_USHRT_MAX},
8033#endif
8034#ifdef _SC_VERSION
8035 {"SC_VERSION", _SC_VERSION},
8036#endif
8037#ifdef _SC_WORD_BIT
8038 {"SC_WORD_BIT", _SC_WORD_BIT},
8039#endif
8040#ifdef _SC_XBS5_ILP32_OFF32
8041 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
8042#endif
8043#ifdef _SC_XBS5_ILP32_OFFBIG
8044 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
8045#endif
8046#ifdef _SC_XBS5_LP64_OFF64
8047 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
8048#endif
8049#ifdef _SC_XBS5_LPBIG_OFFBIG
8050 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
8051#endif
8052#ifdef _SC_XOPEN_CRYPT
8053 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
8054#endif
8055#ifdef _SC_XOPEN_ENH_I18N
8056 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
8057#endif
8058#ifdef _SC_XOPEN_LEGACY
8059 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
8060#endif
8061#ifdef _SC_XOPEN_REALTIME
8062 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
8063#endif
8064#ifdef _SC_XOPEN_REALTIME_THREADS
8065 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
8066#endif
8067#ifdef _SC_XOPEN_SHM
8068 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
8069#endif
8070#ifdef _SC_XOPEN_UNIX
8071 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
8072#endif
8073#ifdef _SC_XOPEN_VERSION
8074 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
8075#endif
8076#ifdef _SC_XOPEN_XCU_VERSION
8077 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
8078#endif
8079#ifdef _SC_XOPEN_XPG2
8080 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
8081#endif
8082#ifdef _SC_XOPEN_XPG3
8083 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
8084#endif
8085#ifdef _SC_XOPEN_XPG4
8086 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
8087#endif
8088};
8089
8090static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008091conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008092{
8093 return conv_confname(arg, valuep, posix_constants_sysconf,
8094 sizeof(posix_constants_sysconf)
8095 / sizeof(struct constdef));
8096}
8097
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008098PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008099"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008100Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008101
8102static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008103posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008104{
8105 PyObject *result = NULL;
8106 int name;
8107
8108 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
8109 int value;
8110
8111 errno = 0;
8112 value = sysconf(name);
8113 if (value == -1 && errno != 0)
8114 posix_error();
8115 else
8116 result = PyInt_FromLong(value);
8117 }
8118 return result;
8119}
8120#endif
8121
8122
Fred Drakebec628d1999-12-15 18:31:10 +00008123/* This code is used to ensure that the tables of configuration value names
8124 * are in sorted order as required by conv_confname(), and also to build the
8125 * the exported dictionaries that are used to publish information about the
8126 * names available on the host platform.
8127 *
8128 * Sorting the table at runtime ensures that the table is properly ordered
8129 * when used, even for platforms we're not able to test on. It also makes
8130 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008131 */
Fred Drakebec628d1999-12-15 18:31:10 +00008132
8133static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008134cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008135{
8136 const struct constdef *c1 =
8137 (const struct constdef *) v1;
8138 const struct constdef *c2 =
8139 (const struct constdef *) v2;
8140
8141 return strcmp(c1->name, c2->name);
8142}
8143
8144static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008145setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008146 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008147{
Fred Drakebec628d1999-12-15 18:31:10 +00008148 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008149 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008150
8151 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8152 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008153 if (d == NULL)
8154 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008155
Barry Warsaw3155db32000-04-13 15:20:40 +00008156 for (i=0; i < tablesize; ++i) {
8157 PyObject *o = PyInt_FromLong(table[i].value);
8158 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8159 Py_XDECREF(o);
8160 Py_DECREF(d);
8161 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008162 }
Barry Warsaw3155db32000-04-13 15:20:40 +00008163 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008164 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008165 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008166}
8167
Fred Drakebec628d1999-12-15 18:31:10 +00008168/* Return -1 on failure, 0 on success. */
8169static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008170setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008171{
8172#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008173 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008174 sizeof(posix_constants_pathconf)
8175 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008176 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008177 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008178#endif
8179#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008180 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008181 sizeof(posix_constants_confstr)
8182 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008183 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008184 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008185#endif
8186#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008187 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008188 sizeof(posix_constants_sysconf)
8189 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008190 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008191 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008192#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008193 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008194}
Fred Draked86ed291999-12-15 15:34:33 +00008195
8196
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008197PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008198"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008199Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008200in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008201
8202static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008203posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008204{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008205 abort();
8206 /*NOTREACHED*/
8207 Py_FatalError("abort() called from Python code didn't abort!");
8208 return NULL;
8209}
Fred Drakebec628d1999-12-15 18:31:10 +00008210
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008211#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008212PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008213"startfile(filepath [, operation]) - Start a file with its associated\n\
8214application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008215\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008216When \"operation\" is not specified or \"open\", this acts like\n\
8217double-clicking the file in Explorer, or giving the file name as an\n\
8218argument to the DOS \"start\" command: the file is opened with whatever\n\
8219application (if any) its extension is associated.\n\
8220When another \"operation\" is given, it specifies what should be done with\n\
8221the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008222\n\
8223startfile returns as soon as the associated application is launched.\n\
8224There is no option to wait for the application to close, and no way\n\
8225to retrieve the application's exit status.\n\
8226\n\
8227The filepath is relative to the current directory. If you want to use\n\
8228an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008229the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008230
8231static PyObject *
8232win32_startfile(PyObject *self, PyObject *args)
8233{
8234 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00008235 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008236 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00008237#ifdef Py_WIN_WIDE_FILENAMES
8238 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008239 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00008240 if (!PyArg_ParseTuple(args, "U|s:startfile",
8241 &unipath, &operation)) {
8242 PyErr_Clear();
8243 goto normal;
8244 }
8245
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008246
8247 if (operation) {
8248 woperation = PyUnicode_DecodeASCII(operation,
8249 strlen(operation), NULL);
8250 if (!woperation) {
8251 PyErr_Clear();
8252 operation = NULL;
8253 goto normal;
8254 }
Georg Brandlad89dc82006-04-03 12:26:26 +00008255 }
8256
8257 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008258 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00008259 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00008260 NULL, NULL, SW_SHOWNORMAL);
8261 Py_END_ALLOW_THREADS
8262
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008263 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00008264 if (rc <= (HINSTANCE)32) {
8265 PyObject *errval = win32_error_unicode("startfile",
8266 PyUnicode_AS_UNICODE(unipath));
8267 return errval;
8268 }
8269 Py_INCREF(Py_None);
8270 return Py_None;
8271 }
8272#endif
8273
8274normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00008275 if (!PyArg_ParseTuple(args, "et|s:startfile",
8276 Py_FileSystemDefaultEncoding, &filepath,
8277 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00008278 return NULL;
8279 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00008280 rc = ShellExecute((HWND)0, operation, filepath,
8281 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008282 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00008283 if (rc <= (HINSTANCE)32) {
8284 PyObject *errval = win32_error("startfile", filepath);
8285 PyMem_Free(filepath);
8286 return errval;
8287 }
8288 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008289 Py_INCREF(Py_None);
8290 return Py_None;
8291}
8292#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008293
Martin v. Löwis438b5342002-12-27 10:16:42 +00008294#ifdef HAVE_GETLOADAVG
8295PyDoc_STRVAR(posix_getloadavg__doc__,
8296"getloadavg() -> (float, float, float)\n\n\
8297Return the number of processes in the system run queue averaged over\n\
8298the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8299was unobtainable");
8300
8301static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008302posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008303{
8304 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008305 if (getloadavg(loadavg, 3)!=3) {
8306 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8307 return NULL;
8308 } else
8309 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8310}
8311#endif
8312
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008313#ifdef MS_WINDOWS
8314
8315PyDoc_STRVAR(win32_urandom__doc__,
8316"urandom(n) -> str\n\n\
8317Return a string of n random bytes suitable for cryptographic use.");
8318
8319typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8320 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8321 DWORD dwFlags );
8322typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8323 BYTE *pbBuffer );
8324
8325static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008326/* This handle is never explicitly released. Instead, the operating
8327 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008328static HCRYPTPROV hCryptProv = 0;
8329
Tim Peters4ad82172004-08-30 17:02:04 +00008330static PyObject*
8331win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008332{
Tim Petersd3115382004-08-30 17:36:46 +00008333 int howMany;
8334 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008335
Tim Peters4ad82172004-08-30 17:02:04 +00008336 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00008337 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00008338 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00008339 if (howMany < 0)
8340 return PyErr_Format(PyExc_ValueError,
8341 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008342
Tim Peters4ad82172004-08-30 17:02:04 +00008343 if (hCryptProv == 0) {
8344 HINSTANCE hAdvAPI32 = NULL;
8345 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008346
Tim Peters4ad82172004-08-30 17:02:04 +00008347 /* Obtain handle to the DLL containing CryptoAPI
8348 This should not fail */
8349 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8350 if(hAdvAPI32 == NULL)
8351 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008352
Tim Peters4ad82172004-08-30 17:02:04 +00008353 /* Obtain pointers to the CryptoAPI functions
8354 This will fail on some early versions of Win95 */
8355 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8356 hAdvAPI32,
8357 "CryptAcquireContextA");
8358 if (pCryptAcquireContext == NULL)
8359 return PyErr_Format(PyExc_NotImplementedError,
8360 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008361
Tim Peters4ad82172004-08-30 17:02:04 +00008362 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8363 hAdvAPI32, "CryptGenRandom");
Georg Brandl74bb7832006-09-06 06:03:59 +00008364 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00008365 return PyErr_Format(PyExc_NotImplementedError,
8366 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008367
Tim Peters4ad82172004-08-30 17:02:04 +00008368 /* Acquire context */
8369 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8370 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8371 return win32_error("CryptAcquireContext", NULL);
8372 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008373
Tim Peters4ad82172004-08-30 17:02:04 +00008374 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008375 result = PyString_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00008376 if (result != NULL) {
8377 /* Get random data */
Amaury Forgeot d'Arc74bd40d2008-07-21 21:06:46 +00008378 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00008379 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008380 PyString_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00008381 Py_DECREF(result);
8382 return win32_error("CryptGenRandom", NULL);
8383 }
Tim Peters4ad82172004-08-30 17:02:04 +00008384 }
Tim Petersd3115382004-08-30 17:36:46 +00008385 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008386}
8387#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008388
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008389#ifdef __VMS
8390/* Use openssl random routine */
8391#include <openssl/rand.h>
8392PyDoc_STRVAR(vms_urandom__doc__,
8393"urandom(n) -> str\n\n\
8394Return a string of n random bytes suitable for cryptographic use.");
8395
8396static PyObject*
8397vms_urandom(PyObject *self, PyObject *args)
8398{
8399 int howMany;
8400 PyObject* result;
8401
8402 /* Read arguments */
8403 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8404 return NULL;
8405 if (howMany < 0)
8406 return PyErr_Format(PyExc_ValueError,
8407 "negative argument not allowed");
8408
8409 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008410 result = PyString_FromStringAndSize(NULL, howMany);
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008411 if (result != NULL) {
8412 /* Get random data */
8413 if (RAND_pseudo_bytes((unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008414 PyString_AS_STRING(result),
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008415 howMany) < 0) {
8416 Py_DECREF(result);
8417 return PyErr_Format(PyExc_ValueError,
8418 "RAND_pseudo_bytes");
8419 }
8420 }
8421 return result;
8422}
8423#endif
8424
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008425static PyMethodDef posix_methods[] = {
8426 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8427#ifdef HAVE_TTYNAME
8428 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8429#endif
8430 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008431#ifdef HAVE_CHFLAGS
8432 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8433#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008434 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008435#ifdef HAVE_FCHMOD
8436 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8437#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008438#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008439 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008440#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008441#ifdef HAVE_LCHMOD
8442 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8443#endif /* HAVE_LCHMOD */
8444#ifdef HAVE_FCHOWN
8445 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8446#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008447#ifdef HAVE_LCHFLAGS
8448 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8449#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008450#ifdef HAVE_LCHOWN
8451 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8452#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008453#ifdef HAVE_CHROOT
8454 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8455#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008456#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00008457 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008458#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008459#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00008460 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008461#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00008462 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008463#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008464#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008465#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008466 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008467#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008468 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8469 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8470 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008471#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008472 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008473#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008474#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008475 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008476#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008477 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8478 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8479 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008480 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008481#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008482 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008483#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008484#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008485 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008486#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008487 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008488#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00008489 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008490#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008491 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8492 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8493 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008494#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00008495 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008496#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008497 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008498#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008499 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8500 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008501#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008502#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008503 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8504 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008505#if defined(PYOS_OS2)
8506 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8507 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8508#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008509#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008510#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008511 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008512#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008513#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008514 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008515#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008516#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008517 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008518#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008519#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008520 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008521#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008522#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008523 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008524#endif /* HAVE_GETEGID */
8525#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008526 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008527#endif /* HAVE_GETEUID */
8528#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008529 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008530#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008531#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008532 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008533#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008534 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008535#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008536 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008537#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008538#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008539 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008540#endif /* HAVE_GETPPID */
8541#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008542 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008543#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008544#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008545 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008546#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008547#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008548 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008549#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008550#ifdef HAVE_KILLPG
8551 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8552#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008553#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008554 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008555#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008556#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008557 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008558#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008559 {"popen2", win32_popen2, METH_VARARGS},
8560 {"popen3", win32_popen3, METH_VARARGS},
8561 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008562 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008563#else
8564#if defined(PYOS_OS2) && defined(PYCC_GCC)
8565 {"popen2", os2emx_popen2, METH_VARARGS},
8566 {"popen3", os2emx_popen3, METH_VARARGS},
8567 {"popen4", os2emx_popen4, METH_VARARGS},
8568#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008569#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008570#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008571#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008572 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008573#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008574#ifdef HAVE_SETEUID
8575 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8576#endif /* HAVE_SETEUID */
8577#ifdef HAVE_SETEGID
8578 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8579#endif /* HAVE_SETEGID */
8580#ifdef HAVE_SETREUID
8581 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8582#endif /* HAVE_SETREUID */
8583#ifdef HAVE_SETREGID
8584 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8585#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008586#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008587 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008588#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008589#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008590 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008591#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008592#ifdef HAVE_GETPGID
8593 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8594#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008595#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008596 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008597#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008598#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008599 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008600#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008601#ifdef HAVE_WAIT3
8602 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8603#endif /* HAVE_WAIT3 */
8604#ifdef HAVE_WAIT4
8605 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8606#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008607#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008608 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008609#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008610#ifdef HAVE_GETSID
8611 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8612#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008613#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008614 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008615#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008616#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008617 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008618#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008619#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008620 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008621#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008622#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008623 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008624#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008625 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8626 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Georg Brandl309501a2008-01-19 20:22:13 +00008627 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008628 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8629 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8630 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8631 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8632 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8633 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8634 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008635 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008636#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008637 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008638#endif
8639#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008640 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008641#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008642#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008643 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8644#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008645#ifdef HAVE_DEVICE_MACROS
8646 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8647 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8648 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8649#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008650#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008651 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008652#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008653#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008654 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008655#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008656#ifdef HAVE_UNSETENV
8657 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8658#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008659 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008660#ifdef HAVE_FCHDIR
8661 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8662#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008663#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008664 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008665#endif
8666#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008667 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008668#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008669#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008670#ifdef WCOREDUMP
8671 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8672#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008673#ifdef WIFCONTINUED
8674 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8675#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008676#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008677 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008678#endif /* WIFSTOPPED */
8679#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008680 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008681#endif /* WIFSIGNALED */
8682#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008683 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008684#endif /* WIFEXITED */
8685#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008686 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008687#endif /* WEXITSTATUS */
8688#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008689 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008690#endif /* WTERMSIG */
8691#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008692 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008693#endif /* WSTOPSIG */
8694#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008695#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008696 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008697#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008698#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008699 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008700#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008701#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008702 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008703#endif
8704#ifdef HAVE_TEMPNAM
8705 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8706#endif
8707#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008708 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008709#endif
Fred Drakec9680921999-12-13 16:37:25 +00008710#ifdef HAVE_CONFSTR
8711 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8712#endif
8713#ifdef HAVE_SYSCONF
8714 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8715#endif
8716#ifdef HAVE_FPATHCONF
8717 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8718#endif
8719#ifdef HAVE_PATHCONF
8720 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8721#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008722 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008723#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008724 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8725#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008726#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008727 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008728#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008729 #ifdef MS_WINDOWS
8730 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8731 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008732 #ifdef __VMS
8733 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8734 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008735 {NULL, NULL} /* Sentinel */
8736};
8737
8738
Barry Warsaw4a342091996-12-19 23:50:02 +00008739static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008740ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008741{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008742 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008743}
8744
Guido van Rossumd48f2521997-12-05 22:19:34 +00008745#if defined(PYOS_OS2)
8746/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008747static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008748{
8749 APIRET rc;
8750 ULONG values[QSV_MAX+1];
8751 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008752 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008753
8754 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008755 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008756 Py_END_ALLOW_THREADS
8757
8758 if (rc != NO_ERROR) {
8759 os2_error(rc);
8760 return -1;
8761 }
8762
Fred Drake4d1e64b2002-04-15 19:40:07 +00008763 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8764 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8765 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8766 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8767 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8768 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8769 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008770
8771 switch (values[QSV_VERSION_MINOR]) {
8772 case 0: ver = "2.00"; break;
8773 case 10: ver = "2.10"; break;
8774 case 11: ver = "2.11"; break;
8775 case 30: ver = "3.00"; break;
8776 case 40: ver = "4.00"; break;
8777 case 50: ver = "5.00"; break;
8778 default:
Tim Peters885d4572001-11-28 20:27:42 +00008779 PyOS_snprintf(tmp, sizeof(tmp),
8780 "%d-%d", values[QSV_VERSION_MAJOR],
8781 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008782 ver = &tmp[0];
8783 }
8784
8785 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008786 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008787 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008788
8789 /* Add Indicator of Which Drive was Used to Boot the System */
8790 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8791 tmp[1] = ':';
8792 tmp[2] = '\0';
8793
Fred Drake4d1e64b2002-04-15 19:40:07 +00008794 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008795}
8796#endif
8797
Barry Warsaw4a342091996-12-19 23:50:02 +00008798static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008799all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008800{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008801#ifdef F_OK
8802 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008803#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008804#ifdef R_OK
8805 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008806#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008807#ifdef W_OK
8808 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008809#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008810#ifdef X_OK
8811 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008812#endif
Fred Drakec9680921999-12-13 16:37:25 +00008813#ifdef NGROUPS_MAX
8814 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8815#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008816#ifdef TMP_MAX
8817 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8818#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008819#ifdef WCONTINUED
8820 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8821#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008822#ifdef WNOHANG
8823 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008824#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008825#ifdef WUNTRACED
8826 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8827#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008828#ifdef O_RDONLY
8829 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8830#endif
8831#ifdef O_WRONLY
8832 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8833#endif
8834#ifdef O_RDWR
8835 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8836#endif
8837#ifdef O_NDELAY
8838 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8839#endif
8840#ifdef O_NONBLOCK
8841 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8842#endif
8843#ifdef O_APPEND
8844 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8845#endif
8846#ifdef O_DSYNC
8847 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8848#endif
8849#ifdef O_RSYNC
8850 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8851#endif
8852#ifdef O_SYNC
8853 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8854#endif
8855#ifdef O_NOCTTY
8856 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8857#endif
8858#ifdef O_CREAT
8859 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8860#endif
8861#ifdef O_EXCL
8862 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8863#endif
8864#ifdef O_TRUNC
8865 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8866#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008867#ifdef O_BINARY
8868 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8869#endif
8870#ifdef O_TEXT
8871 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8872#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008873#ifdef O_LARGEFILE
8874 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8875#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008876#ifdef O_SHLOCK
8877 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8878#endif
8879#ifdef O_EXLOCK
8880 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8881#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008882
Tim Peters5aa91602002-01-30 05:46:57 +00008883/* MS Windows */
8884#ifdef O_NOINHERIT
8885 /* Don't inherit in child processes. */
8886 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8887#endif
8888#ifdef _O_SHORT_LIVED
8889 /* Optimize for short life (keep in memory). */
8890 /* MS forgot to define this one with a non-underscore form too. */
8891 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8892#endif
8893#ifdef O_TEMPORARY
8894 /* Automatically delete when last handle is closed. */
8895 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8896#endif
8897#ifdef O_RANDOM
8898 /* Optimize for random access. */
8899 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8900#endif
8901#ifdef O_SEQUENTIAL
8902 /* Optimize for sequential access. */
8903 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8904#endif
8905
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008906/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00008907#ifdef O_ASYNC
8908 /* Send a SIGIO signal whenever input or output
8909 becomes available on file descriptor */
8910 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8911#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008912#ifdef O_DIRECT
8913 /* Direct disk access. */
8914 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8915#endif
8916#ifdef O_DIRECTORY
8917 /* Must be a directory. */
8918 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8919#endif
8920#ifdef O_NOFOLLOW
8921 /* Do not follow links. */
8922 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8923#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00008924#ifdef O_NOATIME
8925 /* Do not update the access time. */
8926 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8927#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008928
Barry Warsaw5676bd12003-01-07 20:57:09 +00008929 /* These come from sysexits.h */
8930#ifdef EX_OK
8931 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008932#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008933#ifdef EX_USAGE
8934 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008935#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008936#ifdef EX_DATAERR
8937 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008938#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008939#ifdef EX_NOINPUT
8940 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008941#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008942#ifdef EX_NOUSER
8943 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008944#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008945#ifdef EX_NOHOST
8946 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008947#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008948#ifdef EX_UNAVAILABLE
8949 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008950#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008951#ifdef EX_SOFTWARE
8952 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008953#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008954#ifdef EX_OSERR
8955 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008956#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008957#ifdef EX_OSFILE
8958 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008959#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008960#ifdef EX_CANTCREAT
8961 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008962#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008963#ifdef EX_IOERR
8964 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008965#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008966#ifdef EX_TEMPFAIL
8967 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008968#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008969#ifdef EX_PROTOCOL
8970 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008971#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008972#ifdef EX_NOPERM
8973 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008974#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008975#ifdef EX_CONFIG
8976 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008977#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008978#ifdef EX_NOTFOUND
8979 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008980#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008981
Guido van Rossum246bc171999-02-01 23:54:31 +00008982#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008983#if defined(PYOS_OS2) && defined(PYCC_GCC)
8984 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8985 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8986 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8987 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8988 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8989 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8990 if (ins(d, "P_PM", (long)P_PM)) return -1;
8991 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8992 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8993 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8994 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8995 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8996 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8997 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8998 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8999 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9000 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9001 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9002 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9003 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
9004#else
Guido van Rossum7d385291999-02-16 19:38:04 +00009005 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9006 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9007 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9008 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9009 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009010#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009011#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009012
Guido van Rossumd48f2521997-12-05 22:19:34 +00009013#if defined(PYOS_OS2)
9014 if (insertvalues(d)) return -1;
9015#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009016 return 0;
9017}
9018
9019
Tim Peters5aa91602002-01-30 05:46:57 +00009020#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009021#define INITFUNC initnt
9022#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009023
9024#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009025#define INITFUNC initos2
9026#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009027
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009028#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009029#define INITFUNC initposix
9030#define MODNAME "posix"
9031#endif
9032
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009033PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009034INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009035{
Fred Drake4d1e64b2002-04-15 19:40:07 +00009036 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009037
Fred Drake4d1e64b2002-04-15 19:40:07 +00009038 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009039 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00009040 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00009041 if (m == NULL)
9042 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009043
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009044 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009045 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00009046 Py_XINCREF(v);
9047 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009048 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00009049 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009050
Fred Drake4d1e64b2002-04-15 19:40:07 +00009051 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00009052 return;
9053
Fred Drake4d1e64b2002-04-15 19:40:07 +00009054 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00009055 return;
9056
Fred Drake4d1e64b2002-04-15 19:40:07 +00009057 Py_INCREF(PyExc_OSError);
9058 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009059
Guido van Rossumb3d39562000-01-31 18:41:26 +00009060#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00009061 if (posix_putenv_garbage == NULL)
9062 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009063#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009064
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009065 if (!initialized) {
9066 stat_result_desc.name = MODNAME ".stat_result";
9067 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9068 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9069 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9070 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9071 structseq_new = StatResultType.tp_new;
9072 StatResultType.tp_new = statresult_new;
9073
9074 statvfs_result_desc.name = MODNAME ".statvfs_result";
9075 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009076#ifdef NEED_TICKS_PER_SECOND
9077# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
9078 ticks_per_second = sysconf(_SC_CLK_TCK);
9079# elif defined(HZ)
9080 ticks_per_second = HZ;
9081# else
9082 ticks_per_second = 60; /* magic fallback value; may be bogus */
9083# endif
9084#endif
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009085 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009086 Py_INCREF((PyObject*) &StatResultType);
9087 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00009088 Py_INCREF((PyObject*) &StatVFSResultType);
9089 PyModule_AddObject(m, "statvfs_result",
9090 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009091 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009092
9093#ifdef __APPLE__
9094 /*
9095 * Step 2 of weak-linking support on Mac OS X.
9096 *
9097 * The code below removes functions that are not available on the
9098 * currently active platform.
9099 *
9100 * This block allow one to use a python binary that was build on
9101 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9102 * OSX 10.4.
9103 */
9104#ifdef HAVE_FSTATVFS
9105 if (fstatvfs == NULL) {
9106 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9107 return;
9108 }
9109 }
9110#endif /* HAVE_FSTATVFS */
9111
9112#ifdef HAVE_STATVFS
9113 if (statvfs == NULL) {
9114 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9115 return;
9116 }
9117 }
9118#endif /* HAVE_STATVFS */
9119
9120# ifdef HAVE_LCHOWN
9121 if (lchown == NULL) {
9122 if (PyObject_DelAttrString(m, "lchown") == -1) {
9123 return;
9124 }
9125 }
9126#endif /* HAVE_LCHOWN */
9127
9128
9129#endif /* __APPLE__ */
9130
Guido van Rossumb6775db1994-08-01 11:34:53 +00009131}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009132
9133#ifdef __cplusplus
9134}
9135#endif
9136
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009137