blob: 511b3854e38292985ec076d9b5438669120205b5 [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;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002186 /* Overallocate for \\*.*\0 */
2187 len = PyUnicode_GET_SIZE(po);
2188 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2189 if (!wnamebuf) {
2190 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002191 return NULL;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002192 }
2193 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
Hirokazu Yamamoto406d7aa2009-05-04 05:28:39 +00002194 if (len > 0) {
2195 Py_UNICODE wch = wnamebuf[len-1];
2196 if (wch != L'/' && wch != L'\\' && wch != L':')
2197 wnamebuf[len++] = L'\\';
2198 wcscpy(wnamebuf + len, L"*.*");
2199 }
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002200 if ((d = PyList_New(0)) == NULL) {
2201 free(wnamebuf);
2202 return NULL;
2203 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002204 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2205 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002206 int error = GetLastError();
2207 if (error == ERROR_FILE_NOT_FOUND) {
2208 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002209 return d;
2210 }
2211 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002212 win32_error_unicode("FindFirstFileW", wnamebuf);
2213 free(wnamebuf);
2214 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002215 }
2216 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002217 /* Skip over . and .. */
2218 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2219 wcscmp(wFileData.cFileName, L"..") != 0) {
2220 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2221 if (v == NULL) {
2222 Py_DECREF(d);
2223 d = NULL;
2224 break;
2225 }
2226 if (PyList_Append(d, v) != 0) {
2227 Py_DECREF(v);
2228 Py_DECREF(d);
2229 d = NULL;
2230 break;
2231 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002232 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002233 }
Georg Brandl622927b2006-03-07 12:48:03 +00002234 Py_BEGIN_ALLOW_THREADS
2235 result = FindNextFileW(hFindFile, &wFileData);
2236 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002237 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2238 it got to the end of the directory. */
2239 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2240 Py_DECREF(d);
2241 win32_error_unicode("FindNextFileW", wnamebuf);
2242 FindClose(hFindFile);
2243 free(wnamebuf);
2244 return NULL;
2245 }
Georg Brandl622927b2006-03-07 12:48:03 +00002246 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002247
2248 if (FindClose(hFindFile) == FALSE) {
2249 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002250 win32_error_unicode("FindClose", wnamebuf);
2251 free(wnamebuf);
2252 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002253 }
Martin v. Löwise3edaea2006-05-15 05:51:36 +00002254 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002255 return d;
2256 }
2257 /* Drop the argument parsing error as narrow strings
2258 are also valid. */
2259 PyErr_Clear();
2260 }
2261#endif
2262
Tim Peters5aa91602002-01-30 05:46:57 +00002263 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002264 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002265 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002266 if (len > 0) {
2267 char ch = namebuf[len-1];
2268 if (ch != SEP && ch != ALTSEP && ch != ':')
2269 namebuf[len++] = '/';
Hirokazu Yamamoto406d7aa2009-05-04 05:28:39 +00002270 strcpy(namebuf + len, "*.*");
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002271 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002272
Barry Warsaw53699e91996-12-10 23:23:01 +00002273 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002274 return NULL;
2275
2276 hFindFile = FindFirstFile(namebuf, &FileData);
2277 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002278 int error = GetLastError();
2279 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002280 return d;
2281 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002282 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002283 }
2284 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002285 /* Skip over . and .. */
2286 if (strcmp(FileData.cFileName, ".") != 0 &&
2287 strcmp(FileData.cFileName, "..") != 0) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002288 v = PyString_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002289 if (v == NULL) {
2290 Py_DECREF(d);
2291 d = NULL;
2292 break;
2293 }
2294 if (PyList_Append(d, v) != 0) {
2295 Py_DECREF(v);
2296 Py_DECREF(d);
2297 d = NULL;
2298 break;
2299 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002300 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002301 }
Georg Brandl622927b2006-03-07 12:48:03 +00002302 Py_BEGIN_ALLOW_THREADS
2303 result = FindNextFile(hFindFile, &FileData);
2304 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002305 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2306 it got to the end of the directory. */
2307 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2308 Py_DECREF(d);
2309 win32_error("FindNextFile", namebuf);
2310 FindClose(hFindFile);
2311 return NULL;
2312 }
Georg Brandl622927b2006-03-07 12:48:03 +00002313 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002314
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002315 if (FindClose(hFindFile) == FALSE) {
2316 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002317 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002318 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002319
2320 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002321
Tim Peters0bb44a42000-09-15 07:44:49 +00002322#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002323
2324#ifndef MAX_PATH
2325#define MAX_PATH CCHMAXPATH
2326#endif
2327 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002328 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002329 PyObject *d, *v;
2330 char namebuf[MAX_PATH+5];
2331 HDIR hdir = 1;
2332 ULONG srchcnt = 1;
2333 FILEFINDBUF3 ep;
2334 APIRET rc;
2335
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002336 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002337 return NULL;
2338 if (len >= MAX_PATH) {
2339 PyErr_SetString(PyExc_ValueError, "path too long");
2340 return NULL;
2341 }
2342 strcpy(namebuf, name);
2343 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002344 if (*pt == ALTSEP)
2345 *pt = SEP;
2346 if (namebuf[len-1] != SEP)
2347 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002348 strcpy(namebuf + len, "*.*");
2349
2350 if ((d = PyList_New(0)) == NULL)
2351 return NULL;
2352
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002353 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2354 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002355 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002356 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2357 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2358 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002359
2360 if (rc != NO_ERROR) {
2361 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002362 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002363 }
2364
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002365 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002366 do {
2367 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002368 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002369 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002370
2371 strcpy(namebuf, ep.achName);
2372
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002373 /* Leave Case of Name Alone -- In Native Form */
2374 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002375
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002376 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002377 if (v == NULL) {
2378 Py_DECREF(d);
2379 d = NULL;
2380 break;
2381 }
2382 if (PyList_Append(d, v) != 0) {
2383 Py_DECREF(v);
2384 Py_DECREF(d);
2385 d = NULL;
2386 break;
2387 }
2388 Py_DECREF(v);
2389 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2390 }
2391
2392 return d;
2393#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002394
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002395 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002396 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002397 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002398 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002399 int arg_is_unicode = 1;
2400
Georg Brandl05e89b82006-04-11 07:04:06 +00002401 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002402 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2403 arg_is_unicode = 0;
2404 PyErr_Clear();
2405 }
2406 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002407 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002408 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002409 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002410 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002411 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002412 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002413 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002414 return NULL;
2415 }
Georg Brandl622927b2006-03-07 12:48:03 +00002416 for (;;) {
Georg Brandl86cbf812008-07-16 21:31:41 +00002417 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002418 Py_BEGIN_ALLOW_THREADS
2419 ep = readdir(dirp);
2420 Py_END_ALLOW_THREADS
Georg Brandl86cbf812008-07-16 21:31:41 +00002421 if (ep == NULL) {
2422 if (errno == 0) {
2423 break;
2424 } else {
2425 closedir(dirp);
2426 Py_DECREF(d);
2427 return posix_error_with_allocated_filename(name);
2428 }
2429 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002430 if (ep->d_name[0] == '.' &&
2431 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002432 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002433 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002434 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002435 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002436 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002437 d = NULL;
2438 break;
2439 }
Just van Rossum46c97842003-02-25 21:42:15 +00002440#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002441 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002442 PyObject *w;
2443
2444 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002445 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002446 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002447 if (w != NULL) {
2448 Py_DECREF(v);
2449 v = w;
2450 }
2451 else {
2452 /* fall back to the original byte string, as
2453 discussed in patch #683592 */
2454 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002455 }
Just van Rossum46c97842003-02-25 21:42:15 +00002456 }
2457#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002458 if (PyList_Append(d, v) != 0) {
2459 Py_DECREF(v);
2460 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002461 d = NULL;
2462 break;
2463 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002464 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002465 }
2466 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002467 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002468
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002469 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002470
Tim Peters0bb44a42000-09-15 07:44:49 +00002471#endif /* which OS */
2472} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002473
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002474#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002475/* A helper function for abspath on win32 */
2476static PyObject *
2477posix__getfullpathname(PyObject *self, PyObject *args)
2478{
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00002479 /* assume encoded strings won't more than double no of chars */
Mark Hammondef8b6542001-05-13 08:04:26 +00002480 char inbuf[MAX_PATH*2];
2481 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002482 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002483 char outbuf[MAX_PATH*2];
2484 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002485#ifdef Py_WIN_WIDE_FILENAMES
2486 if (unicode_file_names()) {
2487 PyUnicodeObject *po;
2488 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
Hirokazu Yamamotoed29bb42008-11-08 03:46:17 +00002489 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2490 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002491 Py_UNICODE *wtemp;
Hirokazu Yamamotoed29bb42008-11-08 03:46:17 +00002492 DWORD result;
2493 PyObject *v;
2494 result = GetFullPathNameW(wpath,
2495 sizeof(woutbuf)/sizeof(woutbuf[0]),
2496 woutbuf, &wtemp);
2497 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2498 woutbufp = malloc(result * sizeof(Py_UNICODE));
2499 if (!woutbufp)
2500 return PyErr_NoMemory();
2501 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2502 }
2503 if (result)
2504 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2505 else
2506 v = win32_error_unicode("GetFullPathNameW", wpath);
2507 if (woutbufp != woutbuf)
2508 free(woutbufp);
2509 return v;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002510 }
2511 /* Drop the argument parsing error as narrow strings
2512 are also valid. */
2513 PyErr_Clear();
2514 }
2515#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002516 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2517 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002518 &insize))
2519 return NULL;
2520 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2521 outbuf, &temp))
2522 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002523 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2524 return PyUnicode_Decode(outbuf, strlen(outbuf),
2525 Py_FileSystemDefaultEncoding, NULL);
2526 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002527 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002528} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002529#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002530
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002531PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002532"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002533Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002534
Barry Warsaw53699e91996-12-10 23:23:01 +00002535static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002536posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002537{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002538 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002539 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002540 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002541
2542#ifdef Py_WIN_WIDE_FILENAMES
2543 if (unicode_file_names()) {
2544 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002545 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002546 Py_BEGIN_ALLOW_THREADS
2547 /* PyUnicode_AS_UNICODE OK without thread lock as
2548 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002549 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002550 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002551 if (!res)
2552 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002553 Py_INCREF(Py_None);
2554 return Py_None;
2555 }
2556 /* Drop the argument parsing error as narrow strings
2557 are also valid. */
2558 PyErr_Clear();
2559 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002560 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2561 Py_FileSystemDefaultEncoding, &path, &mode))
2562 return NULL;
2563 Py_BEGIN_ALLOW_THREADS
2564 /* PyUnicode_AS_UNICODE OK without thread lock as
2565 it is a simple dereference. */
2566 res = CreateDirectoryA(path, NULL);
2567 Py_END_ALLOW_THREADS
2568 if (!res) {
2569 win32_error("mkdir", path);
2570 PyMem_Free(path);
2571 return NULL;
2572 }
2573 PyMem_Free(path);
2574 Py_INCREF(Py_None);
2575 return Py_None;
2576#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002577
Tim Peters5aa91602002-01-30 05:46:57 +00002578 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002579 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002580 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002581 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002582#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002583 res = mkdir(path);
2584#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002585 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002586#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002587 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002588 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002589 return posix_error_with_allocated_filename(path);
2590 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002591 Py_INCREF(Py_None);
2592 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002593#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002594}
2595
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002596
Neal Norwitz1818ed72006-03-26 00:29:48 +00002597/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2598#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002599#include <sys/resource.h>
2600#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002601
Neal Norwitz1818ed72006-03-26 00:29:48 +00002602
2603#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002604PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002605"nice(inc) -> new_priority\n\n\
2606Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002607
Barry Warsaw53699e91996-12-10 23:23:01 +00002608static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002609posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002610{
2611 int increment, value;
2612
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002613 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002614 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002615
2616 /* There are two flavours of 'nice': one that returns the new
2617 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002618 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2619 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002620
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002621 If we are of the nice family that returns the new priority, we
2622 need to clear errno before the call, and check if errno is filled
2623 before calling posix_error() on a returnvalue of -1, because the
2624 -1 may be the actual new priority! */
2625
2626 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002627 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002628#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002629 if (value == 0)
2630 value = getpriority(PRIO_PROCESS, 0);
2631#endif
2632 if (value == -1 && errno != 0)
2633 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002634 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002635 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002636}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002637#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002638
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002639PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002640"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002641Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002642
Barry Warsaw53699e91996-12-10 23:23:01 +00002643static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002644posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002645{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002646#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002647 PyObject *o1, *o2;
2648 char *p1, *p2;
2649 BOOL result;
2650 if (unicode_file_names()) {
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002651 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2652 goto error;
2653 if (!convert_to_unicode(&o1))
2654 goto error;
2655 if (!convert_to_unicode(&o2)) {
2656 Py_DECREF(o1);
2657 goto error;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002658 }
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002659 Py_BEGIN_ALLOW_THREADS
2660 result = MoveFileW(PyUnicode_AsUnicode(o1),
2661 PyUnicode_AsUnicode(o2));
2662 Py_END_ALLOW_THREADS
2663 Py_DECREF(o1);
2664 Py_DECREF(o2);
2665 if (!result)
2666 return win32_error("rename", NULL);
2667 Py_INCREF(Py_None);
2668 return Py_None;
2669error:
2670 PyErr_Clear();
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002671 }
2672 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2673 return NULL;
2674 Py_BEGIN_ALLOW_THREADS
2675 result = MoveFileA(p1, p2);
2676 Py_END_ALLOW_THREADS
2677 if (!result)
2678 return win32_error("rename", NULL);
2679 Py_INCREF(Py_None);
2680 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002681#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002682 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002683#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002684}
2685
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002686
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002687PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002688"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002689Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002690
Barry Warsaw53699e91996-12-10 23:23:01 +00002691static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002692posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002693{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002694#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002695 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002696#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002697 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002698#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002699}
2700
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002701
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002702PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002703"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002704Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002705
Barry Warsaw53699e91996-12-10 23:23:01 +00002706static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002707posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002708{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002709#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002710 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002711#else
2712 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2713#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002714}
2715
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002716
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002717#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002718PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002719"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002720Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002721
Barry Warsaw53699e91996-12-10 23:23:01 +00002722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002723posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002724{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002725 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002726 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002727 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002728 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002729 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002730 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002731 Py_END_ALLOW_THREADS
2732 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002733}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002734#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002735
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002736
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002737PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002738"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002739Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002740
Barry Warsaw53699e91996-12-10 23:23:01 +00002741static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002742posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002743{
2744 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002745 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002746 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002747 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002748 if (i < 0)
2749 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002750 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002751}
2752
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002753
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002754PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002755"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002756Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002757
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002758PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002759"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002760Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002761
Barry Warsaw53699e91996-12-10 23:23:01 +00002762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002763posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002764{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002765#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002766 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002767#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002768 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002769#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002770}
2771
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002772
Guido van Rossumb6775db1994-08-01 11:34:53 +00002773#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002774PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002775"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002776Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002777
Barry Warsaw53699e91996-12-10 23:23:01 +00002778static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002779posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002780{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002781 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002782 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002783
Barry Warsaw53699e91996-12-10 23:23:01 +00002784 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002785 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002786 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002787 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002788 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002789 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002790 u.sysname,
2791 u.nodename,
2792 u.release,
2793 u.version,
2794 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002795}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002796#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002797
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002798static int
2799extract_time(PyObject *t, long* sec, long* usec)
2800{
2801 long intval;
2802 if (PyFloat_Check(t)) {
2803 double tval = PyFloat_AsDouble(t);
Christian Heimese93237d2007-12-19 02:37:44 +00002804 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002805 if (!intobj)
2806 return -1;
2807 intval = PyInt_AsLong(intobj);
2808 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002809 if (intval == -1 && PyErr_Occurred())
2810 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002811 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002812 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002813 if (*usec < 0)
2814 /* If rounding gave us a negative number,
2815 truncate. */
2816 *usec = 0;
2817 return 0;
2818 }
2819 intval = PyInt_AsLong(t);
2820 if (intval == -1 && PyErr_Occurred())
2821 return -1;
2822 *sec = intval;
2823 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002824 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002825}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002826
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002827PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002828"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002829utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002830Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002831second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002832
Barry Warsaw53699e91996-12-10 23:23:01 +00002833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002834posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002835{
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002836#ifdef Py_WIN_WIDE_FILENAMES
2837 PyObject *arg;
2838 PyUnicodeObject *obwpath;
2839 wchar_t *wpath = NULL;
2840 char *apath = NULL;
2841 HANDLE hFile;
2842 long atimesec, mtimesec, ausec, musec;
2843 FILETIME atime, mtime;
2844 PyObject *result = NULL;
2845
2846 if (unicode_file_names()) {
2847 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2848 wpath = PyUnicode_AS_UNICODE(obwpath);
2849 Py_BEGIN_ALLOW_THREADS
2850 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002851 NULL, OPEN_EXISTING,
2852 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002853 Py_END_ALLOW_THREADS
2854 if (hFile == INVALID_HANDLE_VALUE)
2855 return win32_error_unicode("utime", wpath);
2856 } else
2857 /* Drop the argument parsing error as narrow strings
2858 are also valid. */
2859 PyErr_Clear();
2860 }
2861 if (!wpath) {
2862 if (!PyArg_ParseTuple(args, "etO:utime",
2863 Py_FileSystemDefaultEncoding, &apath, &arg))
2864 return NULL;
2865 Py_BEGIN_ALLOW_THREADS
2866 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002867 NULL, OPEN_EXISTING,
2868 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002869 Py_END_ALLOW_THREADS
2870 if (hFile == INVALID_HANDLE_VALUE) {
2871 win32_error("utime", apath);
2872 PyMem_Free(apath);
2873 return NULL;
2874 }
2875 PyMem_Free(apath);
2876 }
2877
2878 if (arg == Py_None) {
2879 SYSTEMTIME now;
2880 GetSystemTime(&now);
2881 if (!SystemTimeToFileTime(&now, &mtime) ||
2882 !SystemTimeToFileTime(&now, &atime)) {
2883 win32_error("utime", NULL);
2884 goto done;
2885 }
2886 }
2887 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2888 PyErr_SetString(PyExc_TypeError,
2889 "utime() arg 2 must be a tuple (atime, mtime)");
2890 goto done;
2891 }
2892 else {
2893 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2894 &atimesec, &ausec) == -1)
2895 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002896 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002897 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2898 &mtimesec, &musec) == -1)
2899 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002900 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002901 }
2902 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2903 /* Avoid putting the file name into the error here,
2904 as that may confuse the user into believing that
2905 something is wrong with the file, when it also
2906 could be the time stamp that gives a problem. */
2907 win32_error("utime", NULL);
2908 }
2909 Py_INCREF(Py_None);
2910 result = Py_None;
2911done:
2912 CloseHandle(hFile);
2913 return result;
2914#else /* Py_WIN_WIDE_FILENAMES */
2915
Neal Norwitz2adf2102004-06-09 01:46:02 +00002916 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002917 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002918 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002919 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002920
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002921#if defined(HAVE_UTIMES)
2922 struct timeval buf[2];
2923#define ATIME buf[0].tv_sec
2924#define MTIME buf[1].tv_sec
2925#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002926/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002927 struct utimbuf buf;
2928#define ATIME buf.actime
2929#define MTIME buf.modtime
2930#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002931#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002932 time_t buf[2];
2933#define ATIME buf[0]
2934#define MTIME buf[1]
2935#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002936#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002937
Mark Hammond817c9292003-12-03 01:22:38 +00002938
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002939 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002940 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002941 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002942 if (arg == Py_None) {
2943 /* optional time values not given */
2944 Py_BEGIN_ALLOW_THREADS
2945 res = utime(path, NULL);
2946 Py_END_ALLOW_THREADS
2947 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002948 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002949 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002950 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002951 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002952 return NULL;
2953 }
2954 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002955 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002956 &atime, &ausec) == -1) {
2957 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002958 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002959 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002960 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002961 &mtime, &musec) == -1) {
2962 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002963 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002964 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002965 ATIME = atime;
2966 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002967#ifdef HAVE_UTIMES
2968 buf[0].tv_usec = ausec;
2969 buf[1].tv_usec = musec;
2970 Py_BEGIN_ALLOW_THREADS
2971 res = utimes(path, buf);
2972 Py_END_ALLOW_THREADS
2973#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002974 Py_BEGIN_ALLOW_THREADS
2975 res = utime(path, UTIME_ARG);
2976 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002977#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002978 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002979 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002980 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002981 }
Neal Norwitz96652712004-06-06 20:40:27 +00002982 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002983 Py_INCREF(Py_None);
2984 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002985#undef UTIME_ARG
2986#undef ATIME
2987#undef MTIME
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002988#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002989}
2990
Guido van Rossum85e3b011991-06-03 12:42:10 +00002991
Guido van Rossum3b066191991-06-04 19:40:25 +00002992/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002993
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002994PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002995"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002996Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002997
Barry Warsaw53699e91996-12-10 23:23:01 +00002998static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002999posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003000{
3001 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003002 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003003 return NULL;
3004 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00003005 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003006}
3007
Martin v. Löwis114619e2002-10-07 06:44:21 +00003008#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3009static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003010free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003011{
Martin v. Löwis725507b2006-03-07 12:08:51 +00003012 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00003013 for (i = 0; i < count; i++)
3014 PyMem_Free(array[i]);
3015 PyMem_DEL(array);
3016}
3017#endif
3018
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003019
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003020#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003021PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003022"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003023Execute an executable path with arguments, replacing current process.\n\
3024\n\
3025 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003026 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003027
Barry Warsaw53699e91996-12-10 23:23:01 +00003028static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003029posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003030{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003031 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003032 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003033 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003034 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003035 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003036
Guido van Rossum89b33251993-10-22 14:26:06 +00003037 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00003038 argv is a list or tuple of strings. */
3039
Martin v. Löwis114619e2002-10-07 06:44:21 +00003040 if (!PyArg_ParseTuple(args, "etO:execv",
3041 Py_FileSystemDefaultEncoding,
3042 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003043 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003044 if (PyList_Check(argv)) {
3045 argc = PyList_Size(argv);
3046 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003047 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003048 else if (PyTuple_Check(argv)) {
3049 argc = PyTuple_Size(argv);
3050 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003051 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003052 else {
Fred Drake661ea262000-10-24 19:57:45 +00003053 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003054 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00003055 return NULL;
3056 }
3057
Barry Warsaw53699e91996-12-10 23:23:01 +00003058 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003059 if (argvlist == NULL) {
3060 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003061 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003062 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003063 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003064 if (!PyArg_Parse((*getitem)(argv, i), "et",
3065 Py_FileSystemDefaultEncoding,
3066 &argvlist[i])) {
3067 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00003068 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00003069 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003070 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00003071 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003072
Guido van Rossum85e3b011991-06-03 12:42:10 +00003073 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003074 }
3075 argvlist[argc] = NULL;
3076
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003077 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003078
Guido van Rossum85e3b011991-06-03 12:42:10 +00003079 /* If we get here it's definitely an error */
3080
Martin v. Löwis114619e2002-10-07 06:44:21 +00003081 free_string_array(argvlist, argc);
3082 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003083 return posix_error();
3084}
3085
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003086
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003087PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003088"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003089Execute a path with arguments and environment, replacing current process.\n\
3090\n\
3091 path: path of executable file\n\
3092 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003093 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003094
Barry Warsaw53699e91996-12-10 23:23:01 +00003095static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003096posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003097{
3098 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003099 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003100 char **argvlist;
3101 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003102 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003103 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003104 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003105 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003106
3107 /* execve has three arguments: (path, argv, env), where
3108 argv is a list or tuple of strings and env is a dictionary
3109 like posix.environ. */
3110
Martin v. Löwis114619e2002-10-07 06:44:21 +00003111 if (!PyArg_ParseTuple(args, "etOO:execve",
3112 Py_FileSystemDefaultEncoding,
3113 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003114 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003115 if (PyList_Check(argv)) {
3116 argc = PyList_Size(argv);
3117 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003118 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003119 else if (PyTuple_Check(argv)) {
3120 argc = PyTuple_Size(argv);
3121 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003122 }
3123 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003124 PyErr_SetString(PyExc_TypeError,
3125 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003126 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003127 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003128 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003129 PyErr_SetString(PyExc_TypeError,
3130 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003131 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003132 }
3133
Barry Warsaw53699e91996-12-10 23:23:01 +00003134 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003135 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003136 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003137 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003138 }
3139 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003140 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003141 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003142 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003143 &argvlist[i]))
3144 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003145 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003146 goto fail_1;
3147 }
3148 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003149 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003150 argvlist[argc] = NULL;
3151
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003152 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003153 if (i < 0)
3154 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003155 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003156 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003157 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003158 goto fail_1;
3159 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003160 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003161 keys = PyMapping_Keys(env);
3162 vals = PyMapping_Values(env);
3163 if (!keys || !vals)
3164 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003165 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3166 PyErr_SetString(PyExc_TypeError,
3167 "execve(): env.keys() or env.values() is not a list");
3168 goto fail_2;
3169 }
Tim Peters5aa91602002-01-30 05:46:57 +00003170
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003171 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003172 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003173 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003174
3175 key = PyList_GetItem(keys, pos);
3176 val = PyList_GetItem(vals, pos);
3177 if (!key || !val)
3178 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003179
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003180 if (!PyArg_Parse(
3181 key,
3182 "s;execve() arg 3 contains a non-string key",
3183 &k) ||
3184 !PyArg_Parse(
3185 val,
3186 "s;execve() arg 3 contains a non-string value",
3187 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003188 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003189 goto fail_2;
3190 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003191
3192#if defined(PYOS_OS2)
3193 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3194 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3195#endif
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003196 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003197 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003198 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003199 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003200 goto fail_2;
3201 }
Tim Petersc8996f52001-12-03 20:41:00 +00003202 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003203 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003204#if defined(PYOS_OS2)
3205 }
3206#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003207 }
3208 envlist[envc] = 0;
3209
3210 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003211
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003212 /* If we get here it's definitely an error */
3213
3214 (void) posix_error();
3215
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003216 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003217 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003218 PyMem_DEL(envlist[envc]);
3219 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003220 fail_1:
3221 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003222 Py_XDECREF(vals);
3223 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003224 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003225 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003226 return NULL;
3227}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003228#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003229
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003230
Guido van Rossuma1065681999-01-25 23:20:23 +00003231#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003232PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003233"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003234Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003235\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003236 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003237 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003238 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003239
3240static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003241posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003242{
3243 char *path;
3244 PyObject *argv;
3245 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003246 int mode, i;
3247 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003248 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003249 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003250
3251 /* spawnv has three arguments: (mode, path, argv), where
3252 argv is a list or tuple of strings. */
3253
Martin v. Löwis114619e2002-10-07 06:44:21 +00003254 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3255 Py_FileSystemDefaultEncoding,
3256 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003257 return NULL;
3258 if (PyList_Check(argv)) {
3259 argc = PyList_Size(argv);
3260 getitem = PyList_GetItem;
3261 }
3262 else if (PyTuple_Check(argv)) {
3263 argc = PyTuple_Size(argv);
3264 getitem = PyTuple_GetItem;
3265 }
3266 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003267 PyErr_SetString(PyExc_TypeError,
3268 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003269 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003270 return NULL;
3271 }
3272
3273 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003274 if (argvlist == NULL) {
3275 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003276 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003277 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003278 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003279 if (!PyArg_Parse((*getitem)(argv, i), "et",
3280 Py_FileSystemDefaultEncoding,
3281 &argvlist[i])) {
3282 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003283 PyErr_SetString(
3284 PyExc_TypeError,
3285 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003286 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003287 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003288 }
3289 }
3290 argvlist[argc] = NULL;
3291
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003292#if defined(PYOS_OS2) && defined(PYCC_GCC)
3293 Py_BEGIN_ALLOW_THREADS
3294 spawnval = spawnv(mode, path, argvlist);
3295 Py_END_ALLOW_THREADS
3296#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003297 if (mode == _OLD_P_OVERLAY)
3298 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003299
Tim Peters25059d32001-12-07 20:35:43 +00003300 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003301 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003302 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003303#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003304
Martin v. Löwis114619e2002-10-07 06:44:21 +00003305 free_string_array(argvlist, argc);
3306 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003307
Fred Drake699f3522000-06-29 21:12:41 +00003308 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003309 return posix_error();
3310 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003311#if SIZEOF_LONG == SIZEOF_VOID_P
3312 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003313#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003314 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003315#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003316}
3317
3318
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003319PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003320"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003321Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003322\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003323 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003324 path: path of executable file\n\
3325 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003326 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003327
3328static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003329posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003330{
3331 char *path;
3332 PyObject *argv, *env;
3333 char **argvlist;
3334 char **envlist;
3335 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003336 int mode, pos, envc;
3337 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003338 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003339 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003340 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003341
3342 /* spawnve has four arguments: (mode, path, argv, env), where
3343 argv is a list or tuple of strings and env is a dictionary
3344 like posix.environ. */
3345
Martin v. Löwis114619e2002-10-07 06:44:21 +00003346 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3347 Py_FileSystemDefaultEncoding,
3348 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003349 return NULL;
3350 if (PyList_Check(argv)) {
3351 argc = PyList_Size(argv);
3352 getitem = PyList_GetItem;
3353 }
3354 else if (PyTuple_Check(argv)) {
3355 argc = PyTuple_Size(argv);
3356 getitem = PyTuple_GetItem;
3357 }
3358 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003359 PyErr_SetString(PyExc_TypeError,
3360 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003361 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003362 }
3363 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003364 PyErr_SetString(PyExc_TypeError,
3365 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003366 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003367 }
3368
3369 argvlist = PyMem_NEW(char *, argc+1);
3370 if (argvlist == NULL) {
3371 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003372 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003373 }
3374 for (i = 0; i < argc; i++) {
3375 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003376 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003377 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003378 &argvlist[i]))
3379 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003380 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003381 goto fail_1;
3382 }
3383 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003384 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003385 argvlist[argc] = NULL;
3386
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003387 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003388 if (i < 0)
3389 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003390 envlist = PyMem_NEW(char *, i + 1);
3391 if (envlist == NULL) {
3392 PyErr_NoMemory();
3393 goto fail_1;
3394 }
3395 envc = 0;
3396 keys = PyMapping_Keys(env);
3397 vals = PyMapping_Values(env);
3398 if (!keys || !vals)
3399 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003400 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3401 PyErr_SetString(PyExc_TypeError,
3402 "spawnve(): env.keys() or env.values() is not a list");
3403 goto fail_2;
3404 }
Tim Peters5aa91602002-01-30 05:46:57 +00003405
Guido van Rossuma1065681999-01-25 23:20:23 +00003406 for (pos = 0; pos < i; pos++) {
3407 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003408 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003409
3410 key = PyList_GetItem(keys, pos);
3411 val = PyList_GetItem(vals, pos);
3412 if (!key || !val)
3413 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003414
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003415 if (!PyArg_Parse(
3416 key,
3417 "s;spawnve() arg 3 contains a non-string key",
3418 &k) ||
3419 !PyArg_Parse(
3420 val,
3421 "s;spawnve() arg 3 contains a non-string value",
3422 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003423 {
3424 goto fail_2;
3425 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003426 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003427 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003428 if (p == NULL) {
3429 PyErr_NoMemory();
3430 goto fail_2;
3431 }
Tim Petersc8996f52001-12-03 20:41:00 +00003432 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003433 envlist[envc++] = p;
3434 }
3435 envlist[envc] = 0;
3436
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003437#if defined(PYOS_OS2) && defined(PYCC_GCC)
3438 Py_BEGIN_ALLOW_THREADS
3439 spawnval = spawnve(mode, path, argvlist, envlist);
3440 Py_END_ALLOW_THREADS
3441#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003442 if (mode == _OLD_P_OVERLAY)
3443 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003444
3445 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003446 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003447 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003448#endif
Tim Peters25059d32001-12-07 20:35:43 +00003449
Fred Drake699f3522000-06-29 21:12:41 +00003450 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003451 (void) posix_error();
3452 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003453#if SIZEOF_LONG == SIZEOF_VOID_P
3454 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003455#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003456 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003457#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003458
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003459 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003460 while (--envc >= 0)
3461 PyMem_DEL(envlist[envc]);
3462 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003463 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003464 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003465 Py_XDECREF(vals);
3466 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003467 fail_0:
3468 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003469 return res;
3470}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003471
3472/* OS/2 supports spawnvp & spawnvpe natively */
3473#if defined(PYOS_OS2)
3474PyDoc_STRVAR(posix_spawnvp__doc__,
3475"spawnvp(mode, file, args)\n\n\
3476Execute the program 'file' in a new process, using the environment\n\
3477search path to find the file.\n\
3478\n\
3479 mode: mode of process creation\n\
3480 file: executable file name\n\
3481 args: tuple or list of strings");
3482
3483static PyObject *
3484posix_spawnvp(PyObject *self, PyObject *args)
3485{
3486 char *path;
3487 PyObject *argv;
3488 char **argvlist;
3489 int mode, i, argc;
3490 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003491 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003492
3493 /* spawnvp has three arguments: (mode, path, argv), where
3494 argv is a list or tuple of strings. */
3495
3496 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3497 Py_FileSystemDefaultEncoding,
3498 &path, &argv))
3499 return NULL;
3500 if (PyList_Check(argv)) {
3501 argc = PyList_Size(argv);
3502 getitem = PyList_GetItem;
3503 }
3504 else if (PyTuple_Check(argv)) {
3505 argc = PyTuple_Size(argv);
3506 getitem = PyTuple_GetItem;
3507 }
3508 else {
3509 PyErr_SetString(PyExc_TypeError,
3510 "spawnvp() arg 2 must be a tuple or list");
3511 PyMem_Free(path);
3512 return NULL;
3513 }
3514
3515 argvlist = PyMem_NEW(char *, argc+1);
3516 if (argvlist == NULL) {
3517 PyMem_Free(path);
3518 return PyErr_NoMemory();
3519 }
3520 for (i = 0; i < argc; i++) {
3521 if (!PyArg_Parse((*getitem)(argv, i), "et",
3522 Py_FileSystemDefaultEncoding,
3523 &argvlist[i])) {
3524 free_string_array(argvlist, i);
3525 PyErr_SetString(
3526 PyExc_TypeError,
3527 "spawnvp() arg 2 must contain only strings");
3528 PyMem_Free(path);
3529 return NULL;
3530 }
3531 }
3532 argvlist[argc] = NULL;
3533
3534 Py_BEGIN_ALLOW_THREADS
3535#if defined(PYCC_GCC)
3536 spawnval = spawnvp(mode, path, argvlist);
3537#else
3538 spawnval = _spawnvp(mode, path, argvlist);
3539#endif
3540 Py_END_ALLOW_THREADS
3541
3542 free_string_array(argvlist, argc);
3543 PyMem_Free(path);
3544
3545 if (spawnval == -1)
3546 return posix_error();
3547 else
3548 return Py_BuildValue("l", (long) spawnval);
3549}
3550
3551
3552PyDoc_STRVAR(posix_spawnvpe__doc__,
3553"spawnvpe(mode, file, args, env)\n\n\
3554Execute the program 'file' in a new process, using the environment\n\
3555search path to find the file.\n\
3556\n\
3557 mode: mode of process creation\n\
3558 file: executable file name\n\
3559 args: tuple or list of arguments\n\
3560 env: dictionary of strings mapping to strings");
3561
3562static PyObject *
3563posix_spawnvpe(PyObject *self, PyObject *args)
3564{
3565 char *path;
3566 PyObject *argv, *env;
3567 char **argvlist;
3568 char **envlist;
3569 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3570 int mode, i, pos, argc, envc;
3571 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003572 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003573 int lastarg = 0;
3574
3575 /* spawnvpe has four arguments: (mode, path, argv, env), where
3576 argv is a list or tuple of strings and env is a dictionary
3577 like posix.environ. */
3578
3579 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3580 Py_FileSystemDefaultEncoding,
3581 &path, &argv, &env))
3582 return NULL;
3583 if (PyList_Check(argv)) {
3584 argc = PyList_Size(argv);
3585 getitem = PyList_GetItem;
3586 }
3587 else if (PyTuple_Check(argv)) {
3588 argc = PyTuple_Size(argv);
3589 getitem = PyTuple_GetItem;
3590 }
3591 else {
3592 PyErr_SetString(PyExc_TypeError,
3593 "spawnvpe() arg 2 must be a tuple or list");
3594 goto fail_0;
3595 }
3596 if (!PyMapping_Check(env)) {
3597 PyErr_SetString(PyExc_TypeError,
3598 "spawnvpe() arg 3 must be a mapping object");
3599 goto fail_0;
3600 }
3601
3602 argvlist = PyMem_NEW(char *, argc+1);
3603 if (argvlist == NULL) {
3604 PyErr_NoMemory();
3605 goto fail_0;
3606 }
3607 for (i = 0; i < argc; i++) {
3608 if (!PyArg_Parse((*getitem)(argv, i),
3609 "et;spawnvpe() arg 2 must contain only strings",
3610 Py_FileSystemDefaultEncoding,
3611 &argvlist[i]))
3612 {
3613 lastarg = i;
3614 goto fail_1;
3615 }
3616 }
3617 lastarg = argc;
3618 argvlist[argc] = NULL;
3619
3620 i = PyMapping_Size(env);
3621 if (i < 0)
3622 goto fail_1;
3623 envlist = PyMem_NEW(char *, i + 1);
3624 if (envlist == NULL) {
3625 PyErr_NoMemory();
3626 goto fail_1;
3627 }
3628 envc = 0;
3629 keys = PyMapping_Keys(env);
3630 vals = PyMapping_Values(env);
3631 if (!keys || !vals)
3632 goto fail_2;
3633 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3634 PyErr_SetString(PyExc_TypeError,
3635 "spawnvpe(): env.keys() or env.values() is not a list");
3636 goto fail_2;
3637 }
3638
3639 for (pos = 0; pos < i; pos++) {
3640 char *p, *k, *v;
3641 size_t len;
3642
3643 key = PyList_GetItem(keys, pos);
3644 val = PyList_GetItem(vals, pos);
3645 if (!key || !val)
3646 goto fail_2;
3647
3648 if (!PyArg_Parse(
3649 key,
3650 "s;spawnvpe() arg 3 contains a non-string key",
3651 &k) ||
3652 !PyArg_Parse(
3653 val,
3654 "s;spawnvpe() arg 3 contains a non-string value",
3655 &v))
3656 {
3657 goto fail_2;
3658 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003659 len = PyString_Size(key) + PyString_Size(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003660 p = PyMem_NEW(char, len);
3661 if (p == NULL) {
3662 PyErr_NoMemory();
3663 goto fail_2;
3664 }
3665 PyOS_snprintf(p, len, "%s=%s", k, v);
3666 envlist[envc++] = p;
3667 }
3668 envlist[envc] = 0;
3669
3670 Py_BEGIN_ALLOW_THREADS
3671#if defined(PYCC_GCC)
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003672 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003673#else
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003674 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003675#endif
3676 Py_END_ALLOW_THREADS
3677
3678 if (spawnval == -1)
3679 (void) posix_error();
3680 else
3681 res = Py_BuildValue("l", (long) spawnval);
3682
3683 fail_2:
3684 while (--envc >= 0)
3685 PyMem_DEL(envlist[envc]);
3686 PyMem_DEL(envlist);
3687 fail_1:
3688 free_string_array(argvlist, lastarg);
3689 Py_XDECREF(vals);
3690 Py_XDECREF(keys);
3691 fail_0:
3692 PyMem_Free(path);
3693 return res;
3694}
3695#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003696#endif /* HAVE_SPAWNV */
3697
3698
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003699#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003700PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003701"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003702Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3703\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003704Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003705
3706static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003707posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003708{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003709 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003710 if (pid == -1)
3711 return posix_error();
Gregory P. Smithfb7a50f2008-07-14 06:06:48 +00003712 if (pid == 0)
3713 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003714 return PyInt_FromLong(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003715}
3716#endif
3717
3718
Guido van Rossumad0ee831995-03-01 10:34:45 +00003719#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003720PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003721"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003722Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003723Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003724
Barry Warsaw53699e91996-12-10 23:23:01 +00003725static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003726posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003727{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003728 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003729 if (pid == -1)
3730 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003731 if (pid == 0)
3732 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003733 return PyInt_FromLong(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003734}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003735#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003736
Neal Norwitzb59798b2003-03-21 01:43:31 +00003737/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003738/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3739#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003740#define DEV_PTY_FILE "/dev/ptc"
3741#define HAVE_DEV_PTMX
3742#else
3743#define DEV_PTY_FILE "/dev/ptmx"
3744#endif
3745
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003746#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003747#ifdef HAVE_PTY_H
3748#include <pty.h>
3749#else
3750#ifdef HAVE_LIBUTIL_H
3751#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003752#endif /* HAVE_LIBUTIL_H */
3753#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003754#ifdef HAVE_STROPTS_H
3755#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003756#endif
3757#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003758
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003759#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003760PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003761"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003762Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003763
3764static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003765posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003766{
3767 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003768#ifndef HAVE_OPENPTY
3769 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003770#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003771#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003772 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003773#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003774 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003775#endif
3776#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003777
Thomas Wouters70c21a12000-07-14 14:28:33 +00003778#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003779 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3780 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003781#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003782 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3783 if (slave_name == NULL)
3784 return posix_error();
3785
3786 slave_fd = open(slave_name, O_RDWR);
3787 if (slave_fd < 0)
3788 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003789#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003790 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003791 if (master_fd < 0)
3792 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003793 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003794 /* change permission of slave */
3795 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003796 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003797 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003798 }
3799 /* unlock slave */
3800 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003801 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003802 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003803 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003804 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003805 slave_name = ptsname(master_fd); /* get name of slave */
3806 if (slave_name == NULL)
3807 return posix_error();
3808 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3809 if (slave_fd < 0)
3810 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003811#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003812 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3813 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003814#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003815 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003816#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003817#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003818#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003819
Fred Drake8cef4cf2000-06-28 16:40:38 +00003820 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003821
Fred Drake8cef4cf2000-06-28 16:40:38 +00003822}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003823#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003824
3825#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003826PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003827"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003828Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3829Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003830To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003831
3832static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003833posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003834{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003835 int master_fd = -1;
3836 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003837
Fred Drake8cef4cf2000-06-28 16:40:38 +00003838 pid = forkpty(&master_fd, NULL, NULL, NULL);
3839 if (pid == -1)
3840 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003841 if (pid == 0)
3842 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003843 return Py_BuildValue("(li)", pid, master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003844}
3845#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003846
Guido van Rossumad0ee831995-03-01 10:34:45 +00003847#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003848PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003849"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003850Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003851
Barry Warsaw53699e91996-12-10 23:23:01 +00003852static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003853posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003854{
Barry Warsaw53699e91996-12-10 23:23:01 +00003855 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003856}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003857#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003858
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003859
Guido van Rossumad0ee831995-03-01 10:34:45 +00003860#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003861PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003862"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003863Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003864
Barry Warsaw53699e91996-12-10 23:23:01 +00003865static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003866posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003867{
Barry Warsaw53699e91996-12-10 23:23:01 +00003868 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003869}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003870#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003871
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003872
Guido van Rossumad0ee831995-03-01 10:34:45 +00003873#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003874PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003875"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003876Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003877
Barry Warsaw53699e91996-12-10 23:23:01 +00003878static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003879posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003880{
Barry Warsaw53699e91996-12-10 23:23:01 +00003881 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003882}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003883#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003884
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003885
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003886PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003887"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003888Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003889
Barry Warsaw53699e91996-12-10 23:23:01 +00003890static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003891posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003892{
Barry Warsaw53699e91996-12-10 23:23:01 +00003893 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003894}
3895
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003896
Fred Drakec9680921999-12-13 16:37:25 +00003897#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003898PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003899"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003900Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003901
3902static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003903posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003904{
3905 PyObject *result = NULL;
3906
Fred Drakec9680921999-12-13 16:37:25 +00003907#ifdef NGROUPS_MAX
3908#define MAX_GROUPS NGROUPS_MAX
3909#else
3910 /* defined to be 16 on Solaris7, so this should be a small number */
3911#define MAX_GROUPS 64
3912#endif
3913 gid_t grouplist[MAX_GROUPS];
3914 int n;
3915
3916 n = getgroups(MAX_GROUPS, grouplist);
3917 if (n < 0)
3918 posix_error();
3919 else {
3920 result = PyList_New(n);
3921 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003922 int i;
3923 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003924 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003925 if (o == NULL) {
3926 Py_DECREF(result);
3927 result = NULL;
3928 break;
3929 }
3930 PyList_SET_ITEM(result, i, o);
3931 }
3932 }
3933 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003934
Fred Drakec9680921999-12-13 16:37:25 +00003935 return result;
3936}
3937#endif
3938
Martin v. Löwis606edc12002-06-13 21:09:11 +00003939#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003940PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003941"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003942Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003943
3944static PyObject *
3945posix_getpgid(PyObject *self, PyObject *args)
3946{
3947 int pid, pgid;
3948 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3949 return NULL;
3950 pgid = getpgid(pid);
3951 if (pgid < 0)
3952 return posix_error();
3953 return PyInt_FromLong((long)pgid);
3954}
3955#endif /* HAVE_GETPGID */
3956
3957
Guido van Rossumb6775db1994-08-01 11:34:53 +00003958#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003959PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003960"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003961Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003962
Barry Warsaw53699e91996-12-10 23:23:01 +00003963static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003964posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003965{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003966#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003967 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003968#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003969 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003970#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003971}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003972#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003973
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003974
Guido van Rossumb6775db1994-08-01 11:34:53 +00003975#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003976PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003977"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003978Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003979
Barry Warsaw53699e91996-12-10 23:23:01 +00003980static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003981posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003982{
Guido van Rossum64933891994-10-20 21:56:42 +00003983#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003984 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003985#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003986 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003987#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003988 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003989 Py_INCREF(Py_None);
3990 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003991}
3992
Guido van Rossumb6775db1994-08-01 11:34:53 +00003993#endif /* HAVE_SETPGRP */
3994
Guido van Rossumad0ee831995-03-01 10:34:45 +00003995#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003996PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003997"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003998Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003999
Barry Warsaw53699e91996-12-10 23:23:01 +00004000static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004001posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004002{
Christian Heimesd491d712008-02-01 18:49:26 +00004003 return PyInt_FromLong(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004004}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004005#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004006
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004007
Fred Drake12c6e2d1999-12-14 21:25:03 +00004008#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004009PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004010"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004011Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004012
4013static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004014posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004015{
Neal Norwitze241ce82003-02-17 18:17:05 +00004016 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00004017 char *name;
4018 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004019
Fred Drakea30680b2000-12-06 21:24:28 +00004020 errno = 0;
4021 name = getlogin();
4022 if (name == NULL) {
4023 if (errno)
4024 posix_error();
4025 else
4026 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00004027 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00004028 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00004029 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004030 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00004031 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004032
Fred Drake12c6e2d1999-12-14 21:25:03 +00004033 return result;
4034}
4035#endif
4036
Guido van Rossumad0ee831995-03-01 10:34:45 +00004037#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004038PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004039"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004040Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004041
Barry Warsaw53699e91996-12-10 23:23:01 +00004042static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004043posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004044{
Barry Warsaw53699e91996-12-10 23:23:01 +00004045 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004046}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004047#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004048
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004049
Guido van Rossumad0ee831995-03-01 10:34:45 +00004050#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004051PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004052"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004053Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004054
Barry Warsaw53699e91996-12-10 23:23:01 +00004055static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004056posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004057{
Christian Heimesd491d712008-02-01 18:49:26 +00004058 pid_t pid;
4059 int sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004060 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00004061 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004062#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004063 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4064 APIRET rc;
4065 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004066 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004067
4068 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4069 APIRET rc;
4070 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004071 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004072
4073 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004074 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004075#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00004076 if (kill(pid, sig) == -1)
4077 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004078#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004079 Py_INCREF(Py_None);
4080 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004081}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004082#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004083
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004084#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004085PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004086"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004087Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004088
4089static PyObject *
4090posix_killpg(PyObject *self, PyObject *args)
4091{
4092 int pgid, sig;
4093 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
4094 return NULL;
4095 if (killpg(pgid, sig) == -1)
4096 return posix_error();
4097 Py_INCREF(Py_None);
4098 return Py_None;
4099}
4100#endif
4101
Guido van Rossumc0125471996-06-28 18:55:32 +00004102#ifdef HAVE_PLOCK
4103
4104#ifdef HAVE_SYS_LOCK_H
4105#include <sys/lock.h>
4106#endif
4107
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004108PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004109"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004110Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004111
Barry Warsaw53699e91996-12-10 23:23:01 +00004112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004113posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004114{
4115 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004116 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004117 return NULL;
4118 if (plock(op) == -1)
4119 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004120 Py_INCREF(Py_None);
4121 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004122}
4123#endif
4124
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004125
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004126#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004127PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004128"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004129Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004130
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004131#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004132#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004133static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004134async_system(const char *command)
4135{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004136 char errormsg[256], args[1024];
4137 RESULTCODES rcodes;
4138 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004139
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004140 char *shell = getenv("COMSPEC");
4141 if (!shell)
4142 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004143
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004144 /* avoid overflowing the argument buffer */
4145 if (strlen(shell) + 3 + strlen(command) >= 1024)
4146 return ERROR_NOT_ENOUGH_MEMORY
4147
4148 args[0] = '\0';
4149 strcat(args, shell);
4150 strcat(args, "/c ");
4151 strcat(args, command);
4152
4153 /* execute asynchronously, inheriting the environment */
4154 rc = DosExecPgm(errormsg,
4155 sizeof(errormsg),
4156 EXEC_ASYNC,
4157 args,
4158 NULL,
4159 &rcodes,
4160 shell);
4161 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004162}
4163
Guido van Rossumd48f2521997-12-05 22:19:34 +00004164static FILE *
4165popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004166{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004167 int oldfd, tgtfd;
4168 HFILE pipeh[2];
4169 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004170
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004171 /* mode determines which of stdin or stdout is reconnected to
4172 * the pipe to the child
4173 */
4174 if (strchr(mode, 'r') != NULL) {
4175 tgt_fd = 1; /* stdout */
4176 } else if (strchr(mode, 'w')) {
4177 tgt_fd = 0; /* stdin */
4178 } else {
4179 *err = ERROR_INVALID_ACCESS;
4180 return NULL;
4181 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004182
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00004183 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004184 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4185 *err = rc;
4186 return NULL;
4187 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004188
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004189 /* prevent other threads accessing stdio */
4190 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004191
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004192 /* reconnect stdio and execute child */
4193 oldfd = dup(tgtfd);
4194 close(tgtfd);
4195 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4196 DosClose(pipeh[tgtfd]);
4197 rc = async_system(command);
4198 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004199
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004200 /* restore stdio */
4201 dup2(oldfd, tgtfd);
4202 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004203
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004204 /* allow other threads access to stdio */
4205 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004206
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004207 /* if execution of child was successful return file stream */
4208 if (rc == NO_ERROR)
4209 return fdopen(pipeh[1 - tgtfd], mode);
4210 else {
4211 DosClose(pipeh[1 - tgtfd]);
4212 *err = rc;
4213 return NULL;
4214 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004215}
4216
4217static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004218posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004219{
4220 char *name;
4221 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00004222 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004223 FILE *fp;
4224 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004225 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004226 return NULL;
4227 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00004228 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004229 Py_END_ALLOW_THREADS
4230 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004231 return os2_error(err);
4232
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004233 f = PyFile_FromFile(fp, name, mode, fclose);
4234 if (f != NULL)
4235 PyFile_SetBufSize(f, bufsize);
4236 return f;
4237}
4238
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004239#elif defined(PYCC_GCC)
4240
4241/* standard posix version of popen() support */
4242static PyObject *
4243posix_popen(PyObject *self, PyObject *args)
4244{
4245 char *name;
4246 char *mode = "r";
4247 int bufsize = -1;
4248 FILE *fp;
4249 PyObject *f;
4250 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4251 return NULL;
4252 Py_BEGIN_ALLOW_THREADS
4253 fp = popen(name, mode);
4254 Py_END_ALLOW_THREADS
4255 if (fp == NULL)
4256 return posix_error();
4257 f = PyFile_FromFile(fp, name, mode, pclose);
4258 if (f != NULL)
4259 PyFile_SetBufSize(f, bufsize);
4260 return f;
4261}
4262
4263/* fork() under OS/2 has lots'o'warts
4264 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4265 * most of this code is a ripoff of the win32 code, but using the
4266 * capabilities of EMX's C library routines
4267 */
4268
4269/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4270#define POPEN_1 1
4271#define POPEN_2 2
4272#define POPEN_3 3
4273#define POPEN_4 4
4274
4275static PyObject *_PyPopen(char *, int, int, int);
4276static int _PyPclose(FILE *file);
4277
4278/*
4279 * Internal dictionary mapping popen* file pointers to process handles,
4280 * for use when retrieving the process exit code. See _PyPclose() below
4281 * for more information on this dictionary's use.
4282 */
4283static PyObject *_PyPopenProcs = NULL;
4284
4285/* os2emx version of popen2()
4286 *
4287 * The result of this function is a pipe (file) connected to the
4288 * process's stdin, and a pipe connected to the process's stdout.
4289 */
4290
4291static PyObject *
4292os2emx_popen2(PyObject *self, PyObject *args)
4293{
4294 PyObject *f;
4295 int tm=0;
4296
4297 char *cmdstring;
4298 char *mode = "t";
4299 int bufsize = -1;
4300 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4301 return NULL;
4302
4303 if (*mode == 't')
4304 tm = O_TEXT;
4305 else if (*mode != 'b') {
4306 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4307 return NULL;
4308 } else
4309 tm = O_BINARY;
4310
4311 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4312
4313 return f;
4314}
4315
4316/*
4317 * Variation on os2emx.popen2
4318 *
4319 * The result of this function is 3 pipes - the process's stdin,
4320 * stdout and stderr
4321 */
4322
4323static PyObject *
4324os2emx_popen3(PyObject *self, PyObject *args)
4325{
4326 PyObject *f;
4327 int tm = 0;
4328
4329 char *cmdstring;
4330 char *mode = "t";
4331 int bufsize = -1;
4332 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4333 return NULL;
4334
4335 if (*mode == 't')
4336 tm = O_TEXT;
4337 else if (*mode != 'b') {
4338 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4339 return NULL;
4340 } else
4341 tm = O_BINARY;
4342
4343 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4344
4345 return f;
4346}
4347
4348/*
4349 * Variation on os2emx.popen2
4350 *
Tim Peters11b23062003-04-23 02:39:17 +00004351 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004352 * and stdout+stderr combined as a single pipe.
4353 */
4354
4355static PyObject *
4356os2emx_popen4(PyObject *self, PyObject *args)
4357{
4358 PyObject *f;
4359 int tm = 0;
4360
4361 char *cmdstring;
4362 char *mode = "t";
4363 int bufsize = -1;
4364 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4365 return NULL;
4366
4367 if (*mode == 't')
4368 tm = O_TEXT;
4369 else if (*mode != 'b') {
4370 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4371 return NULL;
4372 } else
4373 tm = O_BINARY;
4374
4375 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4376
4377 return f;
4378}
4379
4380/* a couple of structures for convenient handling of multiple
4381 * file handles and pipes
4382 */
4383struct file_ref
4384{
4385 int handle;
4386 int flags;
4387};
4388
4389struct pipe_ref
4390{
4391 int rd;
4392 int wr;
4393};
4394
4395/* The following code is derived from the win32 code */
4396
4397static PyObject *
4398_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4399{
4400 struct file_ref stdio[3];
4401 struct pipe_ref p_fd[3];
4402 FILE *p_s[3];
Christian Heimesd491d712008-02-01 18:49:26 +00004403 int file_count, i, pipe_err;
4404 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004405 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4406 PyObject *f, *p_f[3];
4407
4408 /* file modes for subsequent fdopen's on pipe handles */
4409 if (mode == O_TEXT)
4410 {
4411 rd_mode = "rt";
4412 wr_mode = "wt";
4413 }
4414 else
4415 {
4416 rd_mode = "rb";
4417 wr_mode = "wb";
4418 }
4419
4420 /* prepare shell references */
4421 if ((shell = getenv("EMXSHELL")) == NULL)
4422 if ((shell = getenv("COMSPEC")) == NULL)
4423 {
4424 errno = ENOENT;
4425 return posix_error();
4426 }
4427
4428 sh_name = _getname(shell);
4429 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4430 opt = "/c";
4431 else
4432 opt = "-c";
4433
4434 /* save current stdio fds + their flags, and set not inheritable */
4435 i = pipe_err = 0;
4436 while (pipe_err >= 0 && i < 3)
4437 {
4438 pipe_err = stdio[i].handle = dup(i);
4439 stdio[i].flags = fcntl(i, F_GETFD, 0);
4440 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4441 i++;
4442 }
4443 if (pipe_err < 0)
4444 {
4445 /* didn't get them all saved - clean up and bail out */
4446 int saved_err = errno;
4447 while (i-- > 0)
4448 {
4449 close(stdio[i].handle);
4450 }
4451 errno = saved_err;
4452 return posix_error();
4453 }
4454
4455 /* create pipe ends */
4456 file_count = 2;
4457 if (n == POPEN_3)
4458 file_count = 3;
4459 i = pipe_err = 0;
4460 while ((pipe_err == 0) && (i < file_count))
4461 pipe_err = pipe((int *)&p_fd[i++]);
4462 if (pipe_err < 0)
4463 {
4464 /* didn't get them all made - clean up and bail out */
4465 while (i-- > 0)
4466 {
4467 close(p_fd[i].wr);
4468 close(p_fd[i].rd);
4469 }
4470 errno = EPIPE;
4471 return posix_error();
4472 }
4473
4474 /* change the actual standard IO streams over temporarily,
4475 * making the retained pipe ends non-inheritable
4476 */
4477 pipe_err = 0;
4478
4479 /* - stdin */
4480 if (dup2(p_fd[0].rd, 0) == 0)
4481 {
4482 close(p_fd[0].rd);
4483 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4484 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4485 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4486 {
4487 close(p_fd[0].wr);
4488 pipe_err = -1;
4489 }
4490 }
4491 else
4492 {
4493 pipe_err = -1;
4494 }
4495
4496 /* - stdout */
4497 if (pipe_err == 0)
4498 {
4499 if (dup2(p_fd[1].wr, 1) == 1)
4500 {
4501 close(p_fd[1].wr);
4502 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4503 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4504 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4505 {
4506 close(p_fd[1].rd);
4507 pipe_err = -1;
4508 }
4509 }
4510 else
4511 {
4512 pipe_err = -1;
4513 }
4514 }
4515
4516 /* - stderr, as required */
4517 if (pipe_err == 0)
4518 switch (n)
4519 {
4520 case POPEN_3:
4521 {
4522 if (dup2(p_fd[2].wr, 2) == 2)
4523 {
4524 close(p_fd[2].wr);
4525 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4526 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4527 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4528 {
4529 close(p_fd[2].rd);
4530 pipe_err = -1;
4531 }
4532 }
4533 else
4534 {
4535 pipe_err = -1;
4536 }
4537 break;
4538 }
4539
4540 case POPEN_4:
4541 {
4542 if (dup2(1, 2) != 2)
4543 {
4544 pipe_err = -1;
4545 }
4546 break;
4547 }
4548 }
4549
4550 /* spawn the child process */
4551 if (pipe_err == 0)
4552 {
4553 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4554 if (pipe_pid == -1)
4555 {
4556 pipe_err = -1;
4557 }
4558 else
4559 {
4560 /* save the PID into the FILE structure
4561 * NOTE: this implementation doesn't actually
4562 * take advantage of this, but do it for
4563 * completeness - AIM Apr01
4564 */
4565 for (i = 0; i < file_count; i++)
4566 p_s[i]->_pid = pipe_pid;
4567 }
4568 }
4569
4570 /* reset standard IO to normal */
4571 for (i = 0; i < 3; i++)
4572 {
4573 dup2(stdio[i].handle, i);
4574 fcntl(i, F_SETFD, stdio[i].flags);
4575 close(stdio[i].handle);
4576 }
4577
4578 /* if any remnant problems, clean up and bail out */
4579 if (pipe_err < 0)
4580 {
4581 for (i = 0; i < 3; i++)
4582 {
4583 close(p_fd[i].rd);
4584 close(p_fd[i].wr);
4585 }
4586 errno = EPIPE;
4587 return posix_error_with_filename(cmdstring);
4588 }
4589
4590 /* build tuple of file objects to return */
4591 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4592 PyFile_SetBufSize(p_f[0], bufsize);
4593 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4594 PyFile_SetBufSize(p_f[1], bufsize);
4595 if (n == POPEN_3)
4596 {
4597 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4598 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004599 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004600 }
4601 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004602 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004603
4604 /*
4605 * Insert the files we've created into the process dictionary
4606 * all referencing the list with the process handle and the
4607 * initial number of files (see description below in _PyPclose).
4608 * Since if _PyPclose later tried to wait on a process when all
4609 * handles weren't closed, it could create a deadlock with the
4610 * child, we spend some energy here to try to ensure that we
4611 * either insert all file handles into the dictionary or none
4612 * at all. It's a little clumsy with the various popen modes
4613 * and variable number of files involved.
4614 */
4615 if (!_PyPopenProcs)
4616 {
4617 _PyPopenProcs = PyDict_New();
4618 }
4619
4620 if (_PyPopenProcs)
4621 {
4622 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4623 int ins_rc[3];
4624
4625 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4626 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4627
4628 procObj = PyList_New(2);
4629 pidObj = PyInt_FromLong((long) pipe_pid);
4630 intObj = PyInt_FromLong((long) file_count);
4631
4632 if (procObj && pidObj && intObj)
4633 {
4634 PyList_SetItem(procObj, 0, pidObj);
4635 PyList_SetItem(procObj, 1, intObj);
4636
4637 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4638 if (fileObj[0])
4639 {
4640 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4641 fileObj[0],
4642 procObj);
4643 }
4644 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4645 if (fileObj[1])
4646 {
4647 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4648 fileObj[1],
4649 procObj);
4650 }
4651 if (file_count >= 3)
4652 {
4653 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4654 if (fileObj[2])
4655 {
4656 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4657 fileObj[2],
4658 procObj);
4659 }
4660 }
4661
4662 if (ins_rc[0] < 0 || !fileObj[0] ||
4663 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4664 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4665 {
4666 /* Something failed - remove any dictionary
4667 * entries that did make it.
4668 */
4669 if (!ins_rc[0] && fileObj[0])
4670 {
4671 PyDict_DelItem(_PyPopenProcs,
4672 fileObj[0]);
4673 }
4674 if (!ins_rc[1] && fileObj[1])
4675 {
4676 PyDict_DelItem(_PyPopenProcs,
4677 fileObj[1]);
4678 }
4679 if (!ins_rc[2] && fileObj[2])
4680 {
4681 PyDict_DelItem(_PyPopenProcs,
4682 fileObj[2]);
4683 }
4684 }
4685 }
Tim Peters11b23062003-04-23 02:39:17 +00004686
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004687 /*
4688 * Clean up our localized references for the dictionary keys
4689 * and value since PyDict_SetItem will Py_INCREF any copies
4690 * that got placed in the dictionary.
4691 */
4692 Py_XDECREF(procObj);
4693 Py_XDECREF(fileObj[0]);
4694 Py_XDECREF(fileObj[1]);
4695 Py_XDECREF(fileObj[2]);
4696 }
4697
4698 /* Child is launched. */
4699 return f;
4700}
4701
4702/*
4703 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4704 * exit code for the child process and return as a result of the close.
4705 *
4706 * This function uses the _PyPopenProcs dictionary in order to map the
4707 * input file pointer to information about the process that was
4708 * originally created by the popen* call that created the file pointer.
4709 * The dictionary uses the file pointer as a key (with one entry
4710 * inserted for each file returned by the original popen* call) and a
4711 * single list object as the value for all files from a single call.
4712 * The list object contains the Win32 process handle at [0], and a file
4713 * count at [1], which is initialized to the total number of file
4714 * handles using that list.
4715 *
4716 * This function closes whichever handle it is passed, and decrements
4717 * the file count in the dictionary for the process handle pointed to
4718 * by this file. On the last close (when the file count reaches zero),
4719 * this function will wait for the child process and then return its
4720 * exit code as the result of the close() operation. This permits the
4721 * files to be closed in any order - it is always the close() of the
4722 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004723 *
4724 * NOTE: This function is currently called with the GIL released.
4725 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004726 */
4727
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004728static int _PyPclose(FILE *file)
4729{
4730 int result;
4731 int exit_code;
Christian Heimesd491d712008-02-01 18:49:26 +00004732 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004733 PyObject *procObj, *pidObj, *intObj, *fileObj;
4734 int file_count;
4735#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004736 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004737#endif
4738
4739 /* Close the file handle first, to ensure it can't block the
4740 * child from exiting if it's the last handle.
4741 */
4742 result = fclose(file);
4743
4744#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004745 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004746#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004747 if (_PyPopenProcs)
4748 {
4749 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4750 (procObj = PyDict_GetItem(_PyPopenProcs,
4751 fileObj)) != NULL &&
4752 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4753 (intObj = PyList_GetItem(procObj,1)) != NULL)
4754 {
4755 pipe_pid = (int) PyInt_AsLong(pidObj);
4756 file_count = (int) PyInt_AsLong(intObj);
4757
4758 if (file_count > 1)
4759 {
4760 /* Still other files referencing process */
4761 file_count--;
4762 PyList_SetItem(procObj,1,
4763 PyInt_FromLong((long) file_count));
4764 }
4765 else
4766 {
4767 /* Last file for this process */
4768 if (result != EOF &&
4769 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4770 {
4771 /* extract exit status */
4772 if (WIFEXITED(exit_code))
4773 {
4774 result = WEXITSTATUS(exit_code);
4775 }
4776 else
4777 {
4778 errno = EPIPE;
4779 result = -1;
4780 }
4781 }
4782 else
4783 {
4784 /* Indicate failure - this will cause the file object
4785 * to raise an I/O error and translate the last
4786 * error code from errno. We do have a problem with
4787 * last errors that overlap the normal errno table,
4788 * but that's a consistent problem with the file object.
4789 */
4790 result = -1;
4791 }
4792 }
4793
4794 /* Remove this file pointer from dictionary */
4795 PyDict_DelItem(_PyPopenProcs, fileObj);
4796
4797 if (PyDict_Size(_PyPopenProcs) == 0)
4798 {
4799 Py_DECREF(_PyPopenProcs);
4800 _PyPopenProcs = NULL;
4801 }
4802
4803 } /* if object retrieval ok */
4804
4805 Py_XDECREF(fileObj);
4806 } /* if _PyPopenProcs */
4807
4808#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004809 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004810#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004811 return result;
4812}
4813
4814#endif /* PYCC_??? */
4815
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004816#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004817
4818/*
4819 * Portable 'popen' replacement for Win32.
4820 *
4821 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4822 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004823 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004824 */
4825
4826#include <malloc.h>
4827#include <io.h>
4828#include <fcntl.h>
4829
4830/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4831#define POPEN_1 1
4832#define POPEN_2 2
4833#define POPEN_3 3
4834#define POPEN_4 4
4835
4836static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004837static int _PyPclose(FILE *file);
4838
4839/*
4840 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004841 * for use when retrieving the process exit code. See _PyPclose() below
4842 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004843 */
4844static PyObject *_PyPopenProcs = NULL;
4845
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004846
4847/* popen that works from a GUI.
4848 *
4849 * The result of this function is a pipe (file) connected to the
4850 * processes stdin or stdout, depending on the requested mode.
4851 */
4852
4853static PyObject *
4854posix_popen(PyObject *self, PyObject *args)
4855{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004856 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004857 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004858
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004859 char *cmdstring;
4860 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004861 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004862 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004863 return NULL;
4864
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004865 if (*mode == 'r')
4866 tm = _O_RDONLY;
4867 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004868 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004869 return NULL;
4870 } else
4871 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004872
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004873 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004874 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004875 return NULL;
4876 }
4877
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004878 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004879 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004880 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004881 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004882 else
4883 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4884
4885 return f;
4886}
4887
4888/* Variation on win32pipe.popen
4889 *
4890 * The result of this function is a pipe (file) connected to the
4891 * process's stdin, and a pipe connected to the process's stdout.
4892 */
4893
4894static PyObject *
4895win32_popen2(PyObject *self, PyObject *args)
4896{
4897 PyObject *f;
4898 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004899
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004900 char *cmdstring;
4901 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004902 int bufsize = -1;
4903 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004904 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004905
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004906 if (*mode == 't')
4907 tm = _O_TEXT;
4908 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004909 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004910 return NULL;
4911 } else
4912 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004913
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004914 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004915 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004916 return NULL;
4917 }
4918
4919 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004920
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004921 return f;
4922}
4923
4924/*
4925 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004926 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004927 * The result of this function is 3 pipes - the process's stdin,
4928 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004929 */
4930
4931static PyObject *
4932win32_popen3(PyObject *self, PyObject *args)
4933{
4934 PyObject *f;
4935 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004936
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004937 char *cmdstring;
4938 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004939 int bufsize = -1;
4940 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004941 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004942
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004943 if (*mode == 't')
4944 tm = _O_TEXT;
4945 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004946 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004947 return NULL;
4948 } else
4949 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004950
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004951 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004952 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004953 return NULL;
4954 }
4955
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004956 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004957
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004958 return f;
4959}
4960
4961/*
4962 * Variation on win32pipe.popen
4963 *
Tim Peters5aa91602002-01-30 05:46:57 +00004964 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004965 * and stdout+stderr combined as a single pipe.
4966 */
4967
4968static PyObject *
4969win32_popen4(PyObject *self, PyObject *args)
4970{
4971 PyObject *f;
4972 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004973
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004974 char *cmdstring;
4975 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004976 int bufsize = -1;
4977 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004978 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004979
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004980 if (*mode == 't')
4981 tm = _O_TEXT;
4982 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004983 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004984 return NULL;
4985 } else
4986 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004987
4988 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004989 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004990 return NULL;
4991 }
4992
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004993 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004994
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004995 return f;
4996}
4997
Mark Hammond08501372001-01-31 07:30:29 +00004998static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004999_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005000 HANDLE hStdin,
5001 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00005002 HANDLE hStderr,
5003 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005004{
5005 PROCESS_INFORMATION piProcInfo;
5006 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005007 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005008 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00005009 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005010 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005011 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005012
5013 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00005014 char *comshell;
5015
Tim Peters92e4dd82002-10-05 01:47:34 +00005016 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005017 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00005018 /* x < i, so x fits into an integer */
5019 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005020
5021 /* Explicitly check if we are using COMMAND.COM. If we are
5022 * then use the w9xpopen hack.
5023 */
5024 comshell = s1 + x;
5025 while (comshell >= s1 && *comshell != '\\')
5026 --comshell;
5027 ++comshell;
5028
5029 if (GetVersion() < 0x80000000 &&
5030 _stricmp(comshell, "command.com") != 0) {
5031 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005032 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00005033 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005034 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00005035 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005036 }
5037 else {
5038 /*
Tim Peters402d5982001-08-27 06:37:48 +00005039 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5040 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005041 */
Mark Hammond08501372001-01-31 07:30:29 +00005042 char modulepath[_MAX_PATH];
5043 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005044 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00005045 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005046 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005047 x = i+1;
5048 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00005049 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00005050 strncat(modulepath,
5051 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00005052 (sizeof(modulepath)/sizeof(modulepath[0]))
5053 -strlen(modulepath));
5054 if (stat(modulepath, &statinfo) != 0) {
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005055 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
Tim Peters5aa91602002-01-30 05:46:57 +00005056 /* Eeek - file-not-found - possibly an embedding
5057 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00005058 */
Tim Peters5aa91602002-01-30 05:46:57 +00005059 strncpy(modulepath,
5060 Py_GetExecPrefix(),
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005061 mplen);
5062 modulepath[mplen-1] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00005063 if (modulepath[strlen(modulepath)-1] != '\\')
5064 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00005065 strncat(modulepath,
5066 szConsoleSpawn,
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005067 mplen-strlen(modulepath));
Mark Hammond08501372001-01-31 07:30:29 +00005068 /* No where else to look - raise an easily identifiable
5069 error, rather than leaving Windows to report
5070 "file not found" - as the user is probably blissfully
5071 unaware this shim EXE is used, and it will confuse them.
5072 (well, it confused me for a while ;-)
5073 */
5074 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00005075 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00005076 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00005077 "for popen to work with your shell "
5078 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00005079 szConsoleSpawn);
5080 return FALSE;
5081 }
5082 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005083 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00005084 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005085 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005086
Tim Peters92e4dd82002-10-05 01:47:34 +00005087 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005088 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005089 /* To maintain correct argument passing semantics,
5090 we pass the command-line as it stands, and allow
5091 quoting to be applied. w9xpopen.exe will then
5092 use its argv vector, and re-quote the necessary
5093 args for the ultimate child process.
5094 */
Tim Peters75cdad52001-11-28 22:07:30 +00005095 PyOS_snprintf(
5096 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005097 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005098 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005099 s1,
5100 s3,
5101 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005102 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00005103 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005104 dialog:
5105 "Your program accessed mem currently in use at xxx"
5106 and a hopeful warning about the stability of your
5107 system.
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00005108 Cost is Ctrl+C won't kill children, but anyone
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005109 who cares can have a go!
5110 */
5111 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005112 }
5113 }
5114
5115 /* Could be an else here to try cmd.exe / command.com in the path
5116 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00005117 else {
Tim Peters402d5982001-08-27 06:37:48 +00005118 PyErr_SetString(PyExc_RuntimeError,
5119 "Cannot locate a COMSPEC environment variable to "
5120 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00005121 return FALSE;
5122 }
Tim Peters5aa91602002-01-30 05:46:57 +00005123
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005124 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5125 siStartInfo.cb = sizeof(STARTUPINFO);
5126 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5127 siStartInfo.hStdInput = hStdin;
5128 siStartInfo.hStdOutput = hStdout;
5129 siStartInfo.hStdError = hStderr;
5130 siStartInfo.wShowWindow = SW_HIDE;
5131
5132 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005133 s2,
5134 NULL,
5135 NULL,
5136 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005137 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005138 NULL,
5139 NULL,
5140 &siStartInfo,
5141 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005142 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005143 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005144
Mark Hammondb37a3732000-08-14 04:47:33 +00005145 /* Return process handle */
5146 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005147 return TRUE;
5148 }
Tim Peters402d5982001-08-27 06:37:48 +00005149 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005150 return FALSE;
5151}
5152
5153/* The following code is based off of KB: Q190351 */
5154
5155static PyObject *
5156_PyPopen(char *cmdstring, int mode, int n)
5157{
5158 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5159 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00005160 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005161
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005162 SECURITY_ATTRIBUTES saAttr;
5163 BOOL fSuccess;
5164 int fd1, fd2, fd3;
5165 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00005166 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005167 PyObject *f;
5168
5169 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5170 saAttr.bInheritHandle = TRUE;
5171 saAttr.lpSecurityDescriptor = NULL;
5172
5173 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5174 return win32_error("CreatePipe", NULL);
5175
5176 /* Create new output read handle and the input write handle. Set
5177 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005178 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005179 * being created. */
5180 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005181 GetCurrentProcess(), &hChildStdinWrDup, 0,
5182 FALSE,
5183 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005184 if (!fSuccess)
5185 return win32_error("DuplicateHandle", NULL);
5186
5187 /* Close the inheritable version of ChildStdin
5188 that we're using. */
5189 CloseHandle(hChildStdinWr);
5190
5191 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5192 return win32_error("CreatePipe", NULL);
5193
5194 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005195 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5196 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005197 if (!fSuccess)
5198 return win32_error("DuplicateHandle", NULL);
5199
5200 /* Close the inheritable version of ChildStdout
5201 that we're using. */
5202 CloseHandle(hChildStdoutRd);
5203
5204 if (n != POPEN_4) {
5205 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5206 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005207 fSuccess = DuplicateHandle(GetCurrentProcess(),
5208 hChildStderrRd,
5209 GetCurrentProcess(),
5210 &hChildStderrRdDup, 0,
5211 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005212 if (!fSuccess)
5213 return win32_error("DuplicateHandle", NULL);
5214 /* Close the inheritable version of ChildStdErr that we're using. */
5215 CloseHandle(hChildStderrRd);
5216 }
Tim Peters5aa91602002-01-30 05:46:57 +00005217
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005218 switch (n) {
5219 case POPEN_1:
5220 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5221 case _O_WRONLY | _O_TEXT:
5222 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005223 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005224 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005225 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005226 PyFile_SetBufSize(f, 0);
5227 /* We don't care about these pipes anymore, so close them. */
5228 CloseHandle(hChildStdoutRdDup);
5229 CloseHandle(hChildStderrRdDup);
5230 break;
5231
5232 case _O_RDONLY | _O_TEXT:
5233 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005234 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005235 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005236 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005237 PyFile_SetBufSize(f, 0);
5238 /* We don't care about these pipes anymore, so close them. */
5239 CloseHandle(hChildStdinWrDup);
5240 CloseHandle(hChildStderrRdDup);
5241 break;
5242
5243 case _O_RDONLY | _O_BINARY:
5244 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005245 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005246 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005247 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005248 PyFile_SetBufSize(f, 0);
5249 /* We don't care about these pipes anymore, so close them. */
5250 CloseHandle(hChildStdinWrDup);
5251 CloseHandle(hChildStderrRdDup);
5252 break;
5253
5254 case _O_WRONLY | _O_BINARY:
5255 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005256 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005257 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005258 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005259 PyFile_SetBufSize(f, 0);
5260 /* We don't care about these pipes anymore, so close them. */
5261 CloseHandle(hChildStdoutRdDup);
5262 CloseHandle(hChildStderrRdDup);
5263 break;
5264 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005265 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005266 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005267
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005268 case POPEN_2:
5269 case POPEN_4:
5270 {
5271 char *m1, *m2;
5272 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005273
Tim Peters7dca21e2002-08-19 00:42:29 +00005274 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005275 m1 = "r";
5276 m2 = "w";
5277 } else {
5278 m1 = "rb";
5279 m2 = "wb";
5280 }
5281
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005282 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005283 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005284 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005285 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005286 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005287 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005288 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005289 PyFile_SetBufSize(p2, 0);
5290
5291 if (n != 4)
5292 CloseHandle(hChildStderrRdDup);
5293
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005294 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005295 Py_XDECREF(p1);
5296 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005297 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005298 break;
5299 }
Tim Peters5aa91602002-01-30 05:46:57 +00005300
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005301 case POPEN_3:
5302 {
5303 char *m1, *m2;
5304 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005305
Tim Peters7dca21e2002-08-19 00:42:29 +00005306 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005307 m1 = "r";
5308 m2 = "w";
5309 } else {
5310 m1 = "rb";
5311 m2 = "wb";
5312 }
5313
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005314 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005315 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005316 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005317 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005318 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005319 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005320 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005321 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5322 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005323 PyFile_SetBufSize(p1, 0);
5324 PyFile_SetBufSize(p2, 0);
5325 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005326 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005327 Py_XDECREF(p1);
5328 Py_XDECREF(p2);
5329 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005330 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005331 break;
5332 }
5333 }
5334
5335 if (n == POPEN_4) {
5336 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005337 hChildStdinRd,
5338 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005339 hChildStdoutWr,
5340 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005341 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005342 }
5343 else {
5344 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005345 hChildStdinRd,
5346 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005347 hChildStderrWr,
5348 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005349 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005350 }
5351
Mark Hammondb37a3732000-08-14 04:47:33 +00005352 /*
5353 * Insert the files we've created into the process dictionary
5354 * all referencing the list with the process handle and the
5355 * initial number of files (see description below in _PyPclose).
5356 * Since if _PyPclose later tried to wait on a process when all
5357 * handles weren't closed, it could create a deadlock with the
5358 * child, we spend some energy here to try to ensure that we
5359 * either insert all file handles into the dictionary or none
5360 * at all. It's a little clumsy with the various popen modes
5361 * and variable number of files involved.
5362 */
5363 if (!_PyPopenProcs) {
5364 _PyPopenProcs = PyDict_New();
5365 }
5366
5367 if (_PyPopenProcs) {
5368 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5369 int ins_rc[3];
5370
5371 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5372 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5373
5374 procObj = PyList_New(2);
5375 hProcessObj = PyLong_FromVoidPtr(hProcess);
5376 intObj = PyInt_FromLong(file_count);
5377
5378 if (procObj && hProcessObj && intObj) {
5379 PyList_SetItem(procObj,0,hProcessObj);
5380 PyList_SetItem(procObj,1,intObj);
5381
5382 fileObj[0] = PyLong_FromVoidPtr(f1);
5383 if (fileObj[0]) {
5384 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5385 fileObj[0],
5386 procObj);
5387 }
5388 if (file_count >= 2) {
5389 fileObj[1] = PyLong_FromVoidPtr(f2);
5390 if (fileObj[1]) {
5391 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5392 fileObj[1],
5393 procObj);
5394 }
5395 }
5396 if (file_count >= 3) {
5397 fileObj[2] = PyLong_FromVoidPtr(f3);
5398 if (fileObj[2]) {
5399 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5400 fileObj[2],
5401 procObj);
5402 }
5403 }
5404
5405 if (ins_rc[0] < 0 || !fileObj[0] ||
5406 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5407 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5408 /* Something failed - remove any dictionary
5409 * entries that did make it.
5410 */
5411 if (!ins_rc[0] && fileObj[0]) {
5412 PyDict_DelItem(_PyPopenProcs,
5413 fileObj[0]);
5414 }
5415 if (!ins_rc[1] && fileObj[1]) {
5416 PyDict_DelItem(_PyPopenProcs,
5417 fileObj[1]);
5418 }
5419 if (!ins_rc[2] && fileObj[2]) {
5420 PyDict_DelItem(_PyPopenProcs,
5421 fileObj[2]);
5422 }
5423 }
5424 }
Tim Peters5aa91602002-01-30 05:46:57 +00005425
Mark Hammondb37a3732000-08-14 04:47:33 +00005426 /*
5427 * Clean up our localized references for the dictionary keys
5428 * and value since PyDict_SetItem will Py_INCREF any copies
5429 * that got placed in the dictionary.
5430 */
5431 Py_XDECREF(procObj);
5432 Py_XDECREF(fileObj[0]);
5433 Py_XDECREF(fileObj[1]);
5434 Py_XDECREF(fileObj[2]);
5435 }
5436
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005437 /* Child is launched. Close the parents copy of those pipe
5438 * handles that only the child should have open. You need to
5439 * make sure that no handles to the write end of the output pipe
5440 * are maintained in this process or else the pipe will not close
5441 * when the child process exits and the ReadFile will hang. */
5442
5443 if (!CloseHandle(hChildStdinRd))
5444 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005445
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005446 if (!CloseHandle(hChildStdoutWr))
5447 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005448
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005449 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5450 return win32_error("CloseHandle", NULL);
5451
5452 return f;
5453}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005454
5455/*
5456 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5457 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005458 *
5459 * This function uses the _PyPopenProcs dictionary in order to map the
5460 * input file pointer to information about the process that was
5461 * originally created by the popen* call that created the file pointer.
5462 * The dictionary uses the file pointer as a key (with one entry
5463 * inserted for each file returned by the original popen* call) and a
5464 * single list object as the value for all files from a single call.
5465 * The list object contains the Win32 process handle at [0], and a file
5466 * count at [1], which is initialized to the total number of file
5467 * handles using that list.
5468 *
5469 * This function closes whichever handle it is passed, and decrements
5470 * the file count in the dictionary for the process handle pointed to
5471 * by this file. On the last close (when the file count reaches zero),
5472 * this function will wait for the child process and then return its
5473 * exit code as the result of the close() operation. This permits the
5474 * files to be closed in any order - it is always the close() of the
5475 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005476 *
5477 * NOTE: This function is currently called with the GIL released.
5478 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005479 */
Tim Peters736aa322000-09-01 06:51:24 +00005480
Fredrik Lundh56055a42000-07-23 19:47:12 +00005481static int _PyPclose(FILE *file)
5482{
Fredrik Lundh20318932000-07-26 17:29:12 +00005483 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005484 DWORD exit_code;
5485 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005486 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5487 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005488#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005489 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005490#endif
5491
Fredrik Lundh20318932000-07-26 17:29:12 +00005492 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005493 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005494 */
5495 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005496#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005497 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005498#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005499 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005500 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5501 (procObj = PyDict_GetItem(_PyPopenProcs,
5502 fileObj)) != NULL &&
5503 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5504 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5505
5506 hProcess = PyLong_AsVoidPtr(hProcessObj);
5507 file_count = PyInt_AsLong(intObj);
5508
5509 if (file_count > 1) {
5510 /* Still other files referencing process */
5511 file_count--;
5512 PyList_SetItem(procObj,1,
5513 PyInt_FromLong(file_count));
5514 } else {
5515 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005516 if (result != EOF &&
5517 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5518 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005519 /* Possible truncation here in 16-bit environments, but
5520 * real exit codes are just the lower byte in any event.
5521 */
5522 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005523 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005524 /* Indicate failure - this will cause the file object
5525 * to raise an I/O error and translate the last Win32
5526 * error code from errno. We do have a problem with
5527 * last errors that overlap the normal errno table,
5528 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005529 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005530 if (result != EOF) {
5531 /* If the error wasn't from the fclose(), then
5532 * set errno for the file object error handling.
5533 */
5534 errno = GetLastError();
5535 }
5536 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005537 }
5538
5539 /* Free up the native handle at this point */
5540 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005541 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005542
Mark Hammondb37a3732000-08-14 04:47:33 +00005543 /* Remove this file pointer from dictionary */
5544 PyDict_DelItem(_PyPopenProcs, fileObj);
5545
5546 if (PyDict_Size(_PyPopenProcs) == 0) {
5547 Py_DECREF(_PyPopenProcs);
5548 _PyPopenProcs = NULL;
5549 }
5550
5551 } /* if object retrieval ok */
5552
5553 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005554 } /* if _PyPopenProcs */
5555
Tim Peters736aa322000-09-01 06:51:24 +00005556#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005557 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005558#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005559 return result;
5560}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005561
5562#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005563static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005564posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005565{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005566 char *name;
5567 char *mode = "r";
5568 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005569 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005570 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005571 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005572 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005573 /* Strip mode of binary or text modifiers */
5574 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5575 mode = "r";
5576 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5577 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005578 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005579 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005580 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005581 if (fp == NULL)
5582 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005583 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005584 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005585 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005586 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005587}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005588
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005589#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005590#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005591
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005592
Guido van Rossumb6775db1994-08-01 11:34:53 +00005593#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005594PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005595"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005596Set the current process's user id.");
5597
Barry Warsaw53699e91996-12-10 23:23:01 +00005598static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005599posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005600{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005601 long uid_arg;
5602 uid_t uid;
5603 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005604 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005605 uid = uid_arg;
5606 if (uid != uid_arg) {
5607 PyErr_SetString(PyExc_OverflowError, "user id too big");
5608 return NULL;
5609 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005610 if (setuid(uid) < 0)
5611 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005612 Py_INCREF(Py_None);
5613 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005614}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005615#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005616
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005617
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005618#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005619PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005620"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005621Set the current process's effective user id.");
5622
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005623static PyObject *
5624posix_seteuid (PyObject *self, PyObject *args)
5625{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005626 long euid_arg;
5627 uid_t euid;
5628 if (!PyArg_ParseTuple(args, "l", &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005629 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005630 euid = euid_arg;
5631 if (euid != euid_arg) {
5632 PyErr_SetString(PyExc_OverflowError, "user id too big");
5633 return NULL;
5634 }
5635 if (seteuid(euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005636 return posix_error();
5637 } else {
5638 Py_INCREF(Py_None);
5639 return Py_None;
5640 }
5641}
5642#endif /* HAVE_SETEUID */
5643
5644#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005645PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005646"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005647Set the current process's effective group id.");
5648
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005649static PyObject *
5650posix_setegid (PyObject *self, PyObject *args)
5651{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005652 long egid_arg;
5653 gid_t egid;
5654 if (!PyArg_ParseTuple(args, "l", &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005655 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005656 egid = egid_arg;
5657 if (egid != egid_arg) {
5658 PyErr_SetString(PyExc_OverflowError, "group id too big");
5659 return NULL;
5660 }
5661 if (setegid(egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005662 return posix_error();
5663 } else {
5664 Py_INCREF(Py_None);
5665 return Py_None;
5666 }
5667}
5668#endif /* HAVE_SETEGID */
5669
5670#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005671PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005672"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005673Set the current process's real and effective user ids.");
5674
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005675static PyObject *
5676posix_setreuid (PyObject *self, PyObject *args)
5677{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005678 long ruid_arg, euid_arg;
5679 uid_t ruid, euid;
5680 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005681 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005682 ruid = ruid_arg;
5683 euid = euid_arg;
5684 if (euid != euid_arg || ruid != ruid_arg) {
5685 PyErr_SetString(PyExc_OverflowError, "user id too big");
5686 return NULL;
5687 }
5688 if (setreuid(ruid, euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005689 return posix_error();
5690 } else {
5691 Py_INCREF(Py_None);
5692 return Py_None;
5693 }
5694}
5695#endif /* HAVE_SETREUID */
5696
5697#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005698PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005699"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005700Set the current process's real and effective group ids.");
5701
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005702static PyObject *
5703posix_setregid (PyObject *self, PyObject *args)
5704{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005705 long rgid_arg, egid_arg;
5706 gid_t rgid, egid;
5707 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005708 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005709 rgid = rgid_arg;
5710 egid = egid_arg;
5711 if (egid != egid_arg || rgid != rgid_arg) {
5712 PyErr_SetString(PyExc_OverflowError, "group id too big");
5713 return NULL;
5714 }
5715 if (setregid(rgid, egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005716 return posix_error();
5717 } else {
5718 Py_INCREF(Py_None);
5719 return Py_None;
5720 }
5721}
5722#endif /* HAVE_SETREGID */
5723
Guido van Rossumb6775db1994-08-01 11:34:53 +00005724#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005725PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005726"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005727Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005728
Barry Warsaw53699e91996-12-10 23:23:01 +00005729static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005730posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005731{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005732 long gid_arg;
5733 gid_t gid;
5734 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005735 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005736 gid = gid_arg;
5737 if (gid != gid_arg) {
5738 PyErr_SetString(PyExc_OverflowError, "group id too big");
5739 return NULL;
5740 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005741 if (setgid(gid) < 0)
5742 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005743 Py_INCREF(Py_None);
5744 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005745}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005746#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005747
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005748#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005749PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005750"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005751Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005752
5753static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005754posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005755{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005756 int i, len;
5757 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005758
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005759 if (!PySequence_Check(groups)) {
5760 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5761 return NULL;
5762 }
5763 len = PySequence_Size(groups);
5764 if (len > MAX_GROUPS) {
5765 PyErr_SetString(PyExc_ValueError, "too many groups");
5766 return NULL;
5767 }
5768 for(i = 0; i < len; i++) {
5769 PyObject *elem;
5770 elem = PySequence_GetItem(groups, i);
5771 if (!elem)
5772 return NULL;
5773 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005774 if (!PyLong_Check(elem)) {
5775 PyErr_SetString(PyExc_TypeError,
5776 "groups must be integers");
5777 Py_DECREF(elem);
5778 return NULL;
5779 } else {
5780 unsigned long x = PyLong_AsUnsignedLong(elem);
5781 if (PyErr_Occurred()) {
5782 PyErr_SetString(PyExc_TypeError,
5783 "group id too big");
5784 Py_DECREF(elem);
5785 return NULL;
5786 }
5787 grouplist[i] = x;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005788 /* read back to see if it fits in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00005789 if (grouplist[i] != x) {
5790 PyErr_SetString(PyExc_TypeError,
5791 "group id too big");
5792 Py_DECREF(elem);
5793 return NULL;
5794 }
5795 }
5796 } else {
5797 long x = PyInt_AsLong(elem);
5798 grouplist[i] = x;
5799 if (grouplist[i] != x) {
5800 PyErr_SetString(PyExc_TypeError,
5801 "group id too big");
5802 Py_DECREF(elem);
5803 return NULL;
5804 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005805 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005806 Py_DECREF(elem);
5807 }
5808
5809 if (setgroups(len, grouplist) < 0)
5810 return posix_error();
5811 Py_INCREF(Py_None);
5812 return Py_None;
5813}
5814#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005815
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005816#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005817static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005818wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005819{
5820 PyObject *result;
5821 static PyObject *struct_rusage;
5822
5823 if (pid == -1)
5824 return posix_error();
5825
5826 if (struct_rusage == NULL) {
Christian Heimes000a0742008-01-03 22:16:32 +00005827 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Neal Norwitz05a45592006-03-20 06:30:08 +00005828 if (m == NULL)
5829 return NULL;
5830 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5831 Py_DECREF(m);
5832 if (struct_rusage == NULL)
5833 return NULL;
5834 }
5835
5836 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5837 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5838 if (!result)
5839 return NULL;
5840
5841#ifndef doubletime
5842#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5843#endif
5844
5845 PyStructSequence_SET_ITEM(result, 0,
5846 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5847 PyStructSequence_SET_ITEM(result, 1,
5848 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5849#define SET_INT(result, index, value)\
5850 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5851 SET_INT(result, 2, ru->ru_maxrss);
5852 SET_INT(result, 3, ru->ru_ixrss);
5853 SET_INT(result, 4, ru->ru_idrss);
5854 SET_INT(result, 5, ru->ru_isrss);
5855 SET_INT(result, 6, ru->ru_minflt);
5856 SET_INT(result, 7, ru->ru_majflt);
5857 SET_INT(result, 8, ru->ru_nswap);
5858 SET_INT(result, 9, ru->ru_inblock);
5859 SET_INT(result, 10, ru->ru_oublock);
5860 SET_INT(result, 11, ru->ru_msgsnd);
5861 SET_INT(result, 12, ru->ru_msgrcv);
5862 SET_INT(result, 13, ru->ru_nsignals);
5863 SET_INT(result, 14, ru->ru_nvcsw);
5864 SET_INT(result, 15, ru->ru_nivcsw);
5865#undef SET_INT
5866
5867 if (PyErr_Occurred()) {
5868 Py_DECREF(result);
5869 return NULL;
5870 }
5871
Neal Norwitz9b00a562006-03-20 08:47:12 +00005872 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005873}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005874#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005875
5876#ifdef HAVE_WAIT3
5877PyDoc_STRVAR(posix_wait3__doc__,
5878"wait3(options) -> (pid, status, rusage)\n\n\
5879Wait for completion of a child process.");
5880
5881static PyObject *
5882posix_wait3(PyObject *self, PyObject *args)
5883{
Christian Heimesd491d712008-02-01 18:49:26 +00005884 pid_t pid;
5885 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005886 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005887 WAIT_TYPE status;
5888 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005889
5890 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5891 return NULL;
5892
5893 Py_BEGIN_ALLOW_THREADS
5894 pid = wait3(&status, options, &ru);
5895 Py_END_ALLOW_THREADS
5896
Neal Norwitzd5a37542006-03-20 06:48:34 +00005897 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005898}
5899#endif /* HAVE_WAIT3 */
5900
5901#ifdef HAVE_WAIT4
5902PyDoc_STRVAR(posix_wait4__doc__,
5903"wait4(pid, options) -> (pid, status, rusage)\n\n\
5904Wait for completion of a given child process.");
5905
5906static PyObject *
5907posix_wait4(PyObject *self, PyObject *args)
5908{
Christian Heimesd491d712008-02-01 18:49:26 +00005909 pid_t pid;
5910 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005911 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005912 WAIT_TYPE status;
5913 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005914
5915 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5916 return NULL;
5917
5918 Py_BEGIN_ALLOW_THREADS
5919 pid = wait4(pid, &status, options, &ru);
5920 Py_END_ALLOW_THREADS
5921
Neal Norwitzd5a37542006-03-20 06:48:34 +00005922 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005923}
5924#endif /* HAVE_WAIT4 */
5925
Guido van Rossumb6775db1994-08-01 11:34:53 +00005926#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005927PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005928"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005929Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005930
Barry Warsaw53699e91996-12-10 23:23:01 +00005931static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005932posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005933{
Christian Heimesd491d712008-02-01 18:49:26 +00005934 pid_t pid;
5935 int options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005936 WAIT_TYPE status;
5937 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005938
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005939 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005940 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005941 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005942 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005943 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005944 if (pid == -1)
5945 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005946
5947 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005948}
5949
Tim Petersab034fa2002-02-01 11:27:43 +00005950#elif defined(HAVE_CWAIT)
5951
5952/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005953PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005954"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005955"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005956
5957static PyObject *
5958posix_waitpid(PyObject *self, PyObject *args)
5959{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005960 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005961 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005962
5963 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5964 return NULL;
5965 Py_BEGIN_ALLOW_THREADS
5966 pid = _cwait(&status, pid, options);
5967 Py_END_ALLOW_THREADS
5968 if (pid == -1)
5969 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005970
5971 /* shift the status left a byte so this is more like the POSIX waitpid */
5972 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005973}
5974#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005975
Guido van Rossumad0ee831995-03-01 10:34:45 +00005976#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005977PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005978"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005979Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005980
Barry Warsaw53699e91996-12-10 23:23:01 +00005981static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005982posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005983{
Christian Heimesd491d712008-02-01 18:49:26 +00005984 pid_t pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005985 WAIT_TYPE status;
5986 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005987
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005988 Py_BEGIN_ALLOW_THREADS
5989 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005990 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005991 if (pid == -1)
5992 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005993
5994 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005995}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005996#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005997
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005998
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005999PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006000"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006001Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006002
Barry Warsaw53699e91996-12-10 23:23:01 +00006003static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006004posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006005{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006006#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006007 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006008#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006009#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00006010 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006011#else
6012 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
6013#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006014#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006015}
6016
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006017
Guido van Rossumb6775db1994-08-01 11:34:53 +00006018#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006019PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006020"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006021Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006022
Barry Warsaw53699e91996-12-10 23:23:01 +00006023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006024posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006025{
Ronald Oussoren10168f22006-10-22 10:45:18 +00006026 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00006027 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00006028 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006029 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006030#ifdef Py_USING_UNICODE
6031 int arg_is_unicode = 0;
6032#endif
6033
6034 if (!PyArg_ParseTuple(args, "et:readlink",
6035 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006036 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006037#ifdef Py_USING_UNICODE
6038 v = PySequence_GetItem(args, 0);
Neal Norwitz91a57212007-08-12 17:11:13 +00006039 if (v == NULL) {
6040 PyMem_Free(path);
6041 return NULL;
6042 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006043
6044 if (PyUnicode_Check(v)) {
6045 arg_is_unicode = 1;
6046 }
6047 Py_DECREF(v);
6048#endif
6049
Barry Warsaw53699e91996-12-10 23:23:01 +00006050 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00006051 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00006052 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006053 if (n < 0)
Neal Norwitz91a57212007-08-12 17:11:13 +00006054 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006055
Neal Norwitz91a57212007-08-12 17:11:13 +00006056 PyMem_Free(path);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006057 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006058#ifdef Py_USING_UNICODE
6059 if (arg_is_unicode) {
6060 PyObject *w;
6061
6062 w = PyUnicode_FromEncodedObject(v,
6063 Py_FileSystemDefaultEncoding,
6064 "strict");
6065 if (w != NULL) {
6066 Py_DECREF(v);
6067 v = w;
6068 }
6069 else {
6070 /* fall back to the original byte string, as
6071 discussed in patch #683592 */
6072 PyErr_Clear();
6073 }
6074 }
6075#endif
6076 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006077}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006078#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006079
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006080
Guido van Rossumb6775db1994-08-01 11:34:53 +00006081#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006082PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006083"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006084Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006085
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006086static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006087posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006088{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00006089 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006090}
6091#endif /* HAVE_SYMLINK */
6092
6093
6094#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006095#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6096static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006097system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006098{
6099 ULONG value = 0;
6100
6101 Py_BEGIN_ALLOW_THREADS
6102 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6103 Py_END_ALLOW_THREADS
6104
6105 return value;
6106}
6107
6108static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006109posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006110{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006111 /* Currently Only Uptime is Provided -- Others Later */
6112 return Py_BuildValue("ddddd",
6113 (double)0 /* t.tms_utime / HZ */,
6114 (double)0 /* t.tms_stime / HZ */,
6115 (double)0 /* t.tms_cutime / HZ */,
6116 (double)0 /* t.tms_cstime / HZ */,
6117 (double)system_uptime() / 1000);
6118}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006119#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006120#define NEED_TICKS_PER_SECOND
6121static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006122static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006123posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006124{
6125 struct tms t;
6126 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00006127 errno = 0;
6128 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00006129 if (c == (clock_t) -1)
6130 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006131 return Py_BuildValue("ddddd",
Martin v. Löwis03824e42008-12-29 18:17:34 +00006132 (double)t.tms_utime / ticks_per_second,
6133 (double)t.tms_stime / ticks_per_second,
6134 (double)t.tms_cutime / ticks_per_second,
6135 (double)t.tms_cstime / ticks_per_second,
6136 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006137}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006138#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006139#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006140
6141
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006142#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006143#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006144static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006145posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006146{
6147 FILETIME create, exit, kernel, user;
6148 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006149 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006150 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6151 /* The fields of a FILETIME structure are the hi and lo part
6152 of a 64-bit value expressed in 100 nanosecond units.
6153 1e7 is one second in such units; 1e-7 the inverse.
6154 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6155 */
Barry Warsaw53699e91996-12-10 23:23:01 +00006156 return Py_BuildValue(
6157 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006158 (double)(user.dwHighDateTime*429.4967296 +
6159 user.dwLowDateTime*1e-7),
Georg Brandl0a40ffb2008-02-13 07:20:22 +00006160 (double)(kernel.dwHighDateTime*429.4967296 +
6161 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00006162 (double)0,
6163 (double)0,
6164 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006165}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006166#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006167
6168#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006169PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006170"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006171Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006172#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006173
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006174
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006175#ifdef HAVE_GETSID
6176PyDoc_STRVAR(posix_getsid__doc__,
6177"getsid(pid) -> sid\n\n\
6178Call the system call getsid().");
6179
6180static PyObject *
6181posix_getsid(PyObject *self, PyObject *args)
6182{
Christian Heimesd491d712008-02-01 18:49:26 +00006183 pid_t pid;
6184 int sid;
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006185 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
6186 return NULL;
6187 sid = getsid(pid);
6188 if (sid < 0)
6189 return posix_error();
6190 return PyInt_FromLong((long)sid);
6191}
6192#endif /* HAVE_GETSID */
6193
6194
Guido van Rossumb6775db1994-08-01 11:34:53 +00006195#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006196PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006197"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006198Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006199
Barry Warsaw53699e91996-12-10 23:23:01 +00006200static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006201posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006202{
Guido van Rossum687dd131993-05-17 08:34:16 +00006203 if (setsid() < 0)
6204 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006205 Py_INCREF(Py_None);
6206 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006207}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006208#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006209
Guido van Rossumb6775db1994-08-01 11:34:53 +00006210#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006211PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006212"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006213Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006214
Barry Warsaw53699e91996-12-10 23:23:01 +00006215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006216posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006217{
Christian Heimesd491d712008-02-01 18:49:26 +00006218 pid_t pid;
6219 int pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006220 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00006221 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006222 if (setpgid(pid, pgrp) < 0)
6223 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006224 Py_INCREF(Py_None);
6225 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006226}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006227#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006228
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006229
Guido van Rossumb6775db1994-08-01 11:34:53 +00006230#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006231PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006232"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006233Return the process group associated with the terminal given by a fd.");
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_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006237{
Christian Heimese6a80742008-02-03 19:51:13 +00006238 int fd;
6239 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006240 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006241 return NULL;
6242 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006243 if (pgid < 0)
6244 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006245 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006246}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006247#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006248
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006249
Guido van Rossumb6775db1994-08-01 11:34:53 +00006250#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006251PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006252"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006253Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006254
Barry Warsaw53699e91996-12-10 23:23:01 +00006255static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006256posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006257{
6258 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006259 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006260 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006261 if (tcsetpgrp(fd, pgid) < 0)
6262 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00006263 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00006264 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006265}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006266#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006267
Guido van Rossum687dd131993-05-17 08:34:16 +00006268/* Functions acting on file descriptors */
6269
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006270PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006271"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006272Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006273
Barry Warsaw53699e91996-12-10 23:23:01 +00006274static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006275posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006276{
Mark Hammondef8b6542001-05-13 08:04:26 +00006277 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006278 int flag;
6279 int mode = 0777;
6280 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006281
6282#ifdef MS_WINDOWS
6283 if (unicode_file_names()) {
6284 PyUnicodeObject *po;
6285 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6286 Py_BEGIN_ALLOW_THREADS
6287 /* PyUnicode_AS_UNICODE OK without thread
6288 lock as it is a simple dereference. */
6289 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6290 Py_END_ALLOW_THREADS
6291 if (fd < 0)
6292 return posix_error();
6293 return PyInt_FromLong((long)fd);
6294 }
6295 /* Drop the argument parsing error as narrow strings
6296 are also valid. */
6297 PyErr_Clear();
6298 }
6299#endif
6300
Tim Peters5aa91602002-01-30 05:46:57 +00006301 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006302 Py_FileSystemDefaultEncoding, &file,
6303 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006304 return NULL;
6305
Barry Warsaw53699e91996-12-10 23:23:01 +00006306 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006307 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006308 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006309 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006310 return posix_error_with_allocated_filename(file);
6311 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006312 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006313}
6314
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006315
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006316PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006317"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006318Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006319
Barry Warsaw53699e91996-12-10 23:23:01 +00006320static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006321posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006322{
6323 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006324 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006325 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006326 if (!_PyVerify_fd(fd))
6327 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006328 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006329 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006330 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006331 if (res < 0)
6332 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006333 Py_INCREF(Py_None);
6334 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006335}
6336
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006337
Georg Brandl309501a2008-01-19 20:22:13 +00006338PyDoc_STRVAR(posix_closerange__doc__,
6339"closerange(fd_low, fd_high)\n\n\
6340Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6341
6342static PyObject *
6343posix_closerange(PyObject *self, PyObject *args)
6344{
6345 int fd_from, fd_to, i;
6346 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6347 return NULL;
6348 Py_BEGIN_ALLOW_THREADS
6349 for (i = fd_from; i < fd_to; i++)
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006350 if (_PyVerify_fd(i))
6351 close(i);
Georg Brandl309501a2008-01-19 20:22:13 +00006352 Py_END_ALLOW_THREADS
6353 Py_RETURN_NONE;
6354}
6355
6356
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006357PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006358"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006359Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006360
Barry Warsaw53699e91996-12-10 23:23:01 +00006361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006362posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006363{
6364 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006365 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006366 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006367 if (!_PyVerify_fd(fd))
6368 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006369 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006370 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006371 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006372 if (fd < 0)
6373 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006374 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006375}
6376
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006377
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006378PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006379"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006380Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006381
Barry Warsaw53699e91996-12-10 23:23:01 +00006382static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006383posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006384{
6385 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006386 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006387 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006388 if (!_PyVerify_fd_dup2(fd, fd2))
6389 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006390 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006391 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006392 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006393 if (res < 0)
6394 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006395 Py_INCREF(Py_None);
6396 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006397}
6398
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006399
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006400PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006401"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006402Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006403
Barry Warsaw53699e91996-12-10 23:23:01 +00006404static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006405posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006406{
6407 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006408#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006409 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006410#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006411 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006412#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006413 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006414 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006415 return NULL;
6416#ifdef SEEK_SET
6417 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6418 switch (how) {
6419 case 0: how = SEEK_SET; break;
6420 case 1: how = SEEK_CUR; break;
6421 case 2: how = SEEK_END; break;
6422 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006423#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006424
6425#if !defined(HAVE_LARGEFILE_SUPPORT)
6426 pos = PyInt_AsLong(posobj);
6427#else
6428 pos = PyLong_Check(posobj) ?
6429 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6430#endif
6431 if (PyErr_Occurred())
6432 return NULL;
6433
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006434 if (!_PyVerify_fd(fd))
6435 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006436 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006437#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006438 res = _lseeki64(fd, pos, how);
6439#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006440 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006441#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006442 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006443 if (res < 0)
6444 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006445
6446#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006447 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006448#else
6449 return PyLong_FromLongLong(res);
6450#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006451}
6452
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006453
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006454PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006455"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006456Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006457
Barry Warsaw53699e91996-12-10 23:23:01 +00006458static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006459posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006460{
Guido van Rossum8bac5461996-06-11 18:38:48 +00006461 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006462 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006463 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006464 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006465 if (size < 0) {
6466 errno = EINVAL;
6467 return posix_error();
6468 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006469 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006470 if (buffer == NULL)
6471 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006472 if (!_PyVerify_fd(fd))
6473 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006474 Py_BEGIN_ALLOW_THREADS
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006475 n = read(fd, PyString_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006476 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006477 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006478 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006479 return posix_error();
6480 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006481 if (n != size)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006482 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006483 return buffer;
6484}
6485
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006486
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006487PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006488"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006489Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006490
Barry Warsaw53699e91996-12-10 23:23:01 +00006491static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006492posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006493{
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006494 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006495 int fd;
6496 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006497
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006498 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00006499 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006500 if (!_PyVerify_fd(fd))
6501 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006502 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006503 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00006504 Py_END_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006505 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00006506 if (size < 0)
6507 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006508 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006509}
6510
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006511
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006512PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006513"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006514Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006515
Barry Warsaw53699e91996-12-10 23:23:01 +00006516static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006517posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006518{
6519 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006520 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006521 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006522 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006523 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006524#ifdef __VMS
6525 /* on OpenVMS we must ensure that all bytes are written to the file */
6526 fsync(fd);
6527#endif
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006528 if (!_PyVerify_fd(fd))
6529 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006530 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006531 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006532 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006533 if (res != 0) {
6534#ifdef MS_WINDOWS
6535 return win32_error("fstat", NULL);
6536#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006537 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006538#endif
6539 }
Tim Peters5aa91602002-01-30 05:46:57 +00006540
Martin v. Löwis14694662006-02-03 12:54:16 +00006541 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006542}
6543
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006544
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006545PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006546"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006547Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006548
Barry Warsaw53699e91996-12-10 23:23:01 +00006549static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006550posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006551{
Guido van Rossum687dd131993-05-17 08:34:16 +00006552 int fd;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006553 char *orgmode = "r";
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006554 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006555 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006556 PyObject *f;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006557 char *mode;
6558 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006559 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006560
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006561 /* Sanitize mode. See fileobject.c */
6562 mode = PyMem_MALLOC(strlen(orgmode)+3);
6563 if (!mode) {
6564 PyErr_NoMemory();
6565 return NULL;
6566 }
6567 strcpy(mode, orgmode);
6568 if (_PyFile_SanitizeMode(mode)) {
6569 PyMem_FREE(mode);
Thomas Heller1f043e22002-11-07 16:00:59 +00006570 return NULL;
6571 }
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006572 if (!_PyVerify_fd(fd))
6573 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006574 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006575#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006576 if (mode[0] == 'a') {
6577 /* try to make sure the O_APPEND flag is set */
6578 int flags;
6579 flags = fcntl(fd, F_GETFL);
6580 if (flags != -1)
6581 fcntl(fd, F_SETFL, flags | O_APPEND);
6582 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006583 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006584 /* restore old mode if fdopen failed */
6585 fcntl(fd, F_SETFL, flags);
6586 } else {
6587 fp = fdopen(fd, mode);
6588 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006589#else
6590 fp = fdopen(fd, mode);
6591#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006592 Py_END_ALLOW_THREADS
Neal Norwitzd83eb312007-05-02 04:47:55 +00006593 PyMem_FREE(mode);
Guido van Rossum687dd131993-05-17 08:34:16 +00006594 if (fp == NULL)
6595 return posix_error();
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006596 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006597 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006598 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006599 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006600}
6601
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006602PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006603"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006604Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006605connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006606
6607static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006608posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006609{
6610 int fd;
6611 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6612 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006613 if (!_PyVerify_fd(fd))
6614 return PyBool_FromLong(0);
Fred Drake106c1a02002-04-23 15:58:02 +00006615 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006616}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006617
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006618#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006619PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006620"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006621Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006622
Barry Warsaw53699e91996-12-10 23:23:01 +00006623static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006624posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006625{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006626#if defined(PYOS_OS2)
6627 HFILE read, write;
6628 APIRET rc;
6629
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006630 Py_BEGIN_ALLOW_THREADS
6631 rc = DosCreatePipe( &read, &write, 4096);
6632 Py_END_ALLOW_THREADS
6633 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006634 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006635
6636 return Py_BuildValue("(ii)", read, write);
6637#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006638#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006639 int fds[2];
6640 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006641 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006642 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006643 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006644 if (res != 0)
6645 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006646 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006647#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006648 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006649 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006650 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006651 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006652 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006653 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006654 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006655 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006656 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6657 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006658 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006659#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006660#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006661}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006662#endif /* HAVE_PIPE */
6663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006664
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006665#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006666PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006667"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006668Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006669
Barry Warsaw53699e91996-12-10 23:23:01 +00006670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006671posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006672{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006673 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006674 int mode = 0666;
6675 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006676 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006677 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006678 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006679 res = mkfifo(filename, mode);
6680 Py_END_ALLOW_THREADS
6681 if (res < 0)
6682 return posix_error();
6683 Py_INCREF(Py_None);
6684 return Py_None;
6685}
6686#endif
6687
6688
Neal Norwitz11690112002-07-30 01:08:28 +00006689#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006690PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006691"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006692Create a filesystem node (file, device special file or named pipe)\n\
6693named filename. mode specifies both the permissions to use and the\n\
6694type of node to be created, being combined (bitwise OR) with one of\n\
6695S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006696device defines the newly created device special file (probably using\n\
6697os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006698
6699
6700static PyObject *
6701posix_mknod(PyObject *self, PyObject *args)
6702{
6703 char *filename;
6704 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006705 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006706 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006707 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006708 return NULL;
6709 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006710 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006711 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006712 if (res < 0)
6713 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006714 Py_INCREF(Py_None);
6715 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006716}
6717#endif
6718
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006719#ifdef HAVE_DEVICE_MACROS
6720PyDoc_STRVAR(posix_major__doc__,
6721"major(device) -> major number\n\
6722Extracts a device major number from a raw device number.");
6723
6724static PyObject *
6725posix_major(PyObject *self, PyObject *args)
6726{
6727 int device;
6728 if (!PyArg_ParseTuple(args, "i:major", &device))
6729 return NULL;
6730 return PyInt_FromLong((long)major(device));
6731}
6732
6733PyDoc_STRVAR(posix_minor__doc__,
6734"minor(device) -> minor number\n\
6735Extracts a device minor number from a raw device number.");
6736
6737static PyObject *
6738posix_minor(PyObject *self, PyObject *args)
6739{
6740 int device;
6741 if (!PyArg_ParseTuple(args, "i:minor", &device))
6742 return NULL;
6743 return PyInt_FromLong((long)minor(device));
6744}
6745
6746PyDoc_STRVAR(posix_makedev__doc__,
6747"makedev(major, minor) -> device number\n\
6748Composes a raw device number from the major and minor device numbers.");
6749
6750static PyObject *
6751posix_makedev(PyObject *self, PyObject *args)
6752{
6753 int major, minor;
6754 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6755 return NULL;
6756 return PyInt_FromLong((long)makedev(major, minor));
6757}
6758#endif /* device macros */
6759
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006760
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006761#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006762PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006763"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006764Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006765
Barry Warsaw53699e91996-12-10 23:23:01 +00006766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006767posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006768{
6769 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006770 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006771 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006772 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006773
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006774 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006775 return NULL;
6776
6777#if !defined(HAVE_LARGEFILE_SUPPORT)
6778 length = PyInt_AsLong(lenobj);
6779#else
6780 length = PyLong_Check(lenobj) ?
6781 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6782#endif
6783 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006784 return NULL;
6785
Barry Warsaw53699e91996-12-10 23:23:01 +00006786 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006787 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006788 Py_END_ALLOW_THREADS
Benjamin Peterson943a6dd2009-01-19 15:51:27 +00006789 if (res < 0)
6790 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006791 Py_INCREF(Py_None);
6792 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006793}
6794#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006795
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006796#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006797PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006798"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006799Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006800
Fred Drake762e2061999-08-26 17:23:54 +00006801/* Save putenv() parameters as values here, so we can collect them when they
6802 * get re-set with another call for the same key. */
6803static PyObject *posix_putenv_garbage;
6804
Tim Peters5aa91602002-01-30 05:46:57 +00006805static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006806posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006807{
6808 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006809 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006810 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006811 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006812
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006813 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006814 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006815
6816#if defined(PYOS_OS2)
6817 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6818 APIRET rc;
6819
Guido van Rossumd48f2521997-12-05 22:19:34 +00006820 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6821 if (rc != NO_ERROR)
6822 return os2_error(rc);
6823
6824 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6825 APIRET rc;
6826
Guido van Rossumd48f2521997-12-05 22:19:34 +00006827 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6828 if (rc != NO_ERROR)
6829 return os2_error(rc);
6830 } else {
6831#endif
6832
Fred Drake762e2061999-08-26 17:23:54 +00006833 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006834 len = strlen(s1) + strlen(s2) + 2;
6835 /* len includes space for a trailing \0; the size arg to
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006836 PyString_FromStringAndSize does not count that */
6837 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006838 if (newstr == NULL)
6839 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006840 newenv = PyString_AS_STRING(newstr);
Anthony Baxter64182fe2006-04-11 12:14:09 +00006841 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6842 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006843 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006844 posix_error();
6845 return NULL;
6846 }
Fred Drake762e2061999-08-26 17:23:54 +00006847 /* Install the first arg and newstr in posix_putenv_garbage;
6848 * this will cause previous value to be collected. This has to
6849 * happen after the real putenv() call because the old value
6850 * was still accessible until then. */
6851 if (PyDict_SetItem(posix_putenv_garbage,
6852 PyTuple_GET_ITEM(args, 0), newstr)) {
6853 /* really not much we can do; just leak */
6854 PyErr_Clear();
6855 }
6856 else {
6857 Py_DECREF(newstr);
6858 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006859
6860#if defined(PYOS_OS2)
6861 }
6862#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006863 Py_INCREF(Py_None);
6864 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006865}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006866#endif /* putenv */
6867
Guido van Rossumc524d952001-10-19 01:31:59 +00006868#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006869PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006870"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006871Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006872
6873static PyObject *
6874posix_unsetenv(PyObject *self, PyObject *args)
6875{
6876 char *s1;
6877
6878 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6879 return NULL;
6880
6881 unsetenv(s1);
6882
6883 /* Remove the key from posix_putenv_garbage;
6884 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006885 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006886 * old value was still accessible until then.
6887 */
6888 if (PyDict_DelItem(posix_putenv_garbage,
6889 PyTuple_GET_ITEM(args, 0))) {
6890 /* really not much we can do; just leak */
6891 PyErr_Clear();
6892 }
6893
6894 Py_INCREF(Py_None);
6895 return Py_None;
6896}
6897#endif /* unsetenv */
6898
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006899PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006900"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006901Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006902
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006903static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006904posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006905{
6906 int code;
6907 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006908 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006909 return NULL;
6910 message = strerror(code);
6911 if (message == NULL) {
6912 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006913 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006914 return NULL;
6915 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006916 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006917}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006918
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006919
Guido van Rossumc9641791998-08-04 15:26:23 +00006920#ifdef HAVE_SYS_WAIT_H
6921
Fred Drake106c1a02002-04-23 15:58:02 +00006922#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006923PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006924"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006925Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006926
6927static PyObject *
6928posix_WCOREDUMP(PyObject *self, PyObject *args)
6929{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006930 WAIT_TYPE status;
6931 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006932
Neal Norwitzd5a37542006-03-20 06:48:34 +00006933 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006934 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006935
6936 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006937}
6938#endif /* WCOREDUMP */
6939
6940#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006941PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006942"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006943Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006944job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006945
6946static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006947posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006948{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006949 WAIT_TYPE status;
6950 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006951
Neal Norwitzd5a37542006-03-20 06:48:34 +00006952 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006953 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006954
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006955 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006956}
6957#endif /* WIFCONTINUED */
6958
Guido van Rossumc9641791998-08-04 15:26:23 +00006959#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006960PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006961"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006962Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006963
6964static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006965posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006966{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006967 WAIT_TYPE status;
6968 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006969
Neal Norwitzd5a37542006-03-20 06:48:34 +00006970 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006971 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006972
Fred Drake106c1a02002-04-23 15:58:02 +00006973 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006974}
6975#endif /* WIFSTOPPED */
6976
6977#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006978PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006979"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006980Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006981
6982static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006983posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006984{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006985 WAIT_TYPE status;
6986 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006987
Neal Norwitzd5a37542006-03-20 06:48:34 +00006988 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006989 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006990
Fred Drake106c1a02002-04-23 15:58:02 +00006991 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006992}
6993#endif /* WIFSIGNALED */
6994
6995#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006996PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006997"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006998Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006999system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007000
7001static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007002posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007003{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007004 WAIT_TYPE status;
7005 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007006
Neal Norwitzd5a37542006-03-20 06:48:34 +00007007 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007008 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007009
Fred Drake106c1a02002-04-23 15:58:02 +00007010 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007011}
7012#endif /* WIFEXITED */
7013
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007014#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007015PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007016"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007017Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007018
7019static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007020posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007021{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007022 WAIT_TYPE status;
7023 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007024
Neal Norwitzd5a37542006-03-20 06:48:34 +00007025 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007026 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007027
Guido van Rossumc9641791998-08-04 15:26:23 +00007028 return Py_BuildValue("i", WEXITSTATUS(status));
7029}
7030#endif /* WEXITSTATUS */
7031
7032#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007033PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007034"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007035Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007036value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007037
7038static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007039posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007040{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007041 WAIT_TYPE status;
7042 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007043
Neal Norwitzd5a37542006-03-20 06:48:34 +00007044 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007045 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007046
Guido van Rossumc9641791998-08-04 15:26:23 +00007047 return Py_BuildValue("i", WTERMSIG(status));
7048}
7049#endif /* WTERMSIG */
7050
7051#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007052PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007053"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007054Return the signal that stopped the process that provided\n\
7055the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007056
7057static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007058posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007059{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007060 WAIT_TYPE status;
7061 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007062
Neal Norwitzd5a37542006-03-20 06:48:34 +00007063 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007064 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007065
Guido van Rossumc9641791998-08-04 15:26:23 +00007066 return Py_BuildValue("i", WSTOPSIG(status));
7067}
7068#endif /* WSTOPSIG */
7069
7070#endif /* HAVE_SYS_WAIT_H */
7071
7072
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007073#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007074#ifdef _SCO_DS
7075/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7076 needed definitions in sys/statvfs.h */
7077#define _SVID3
7078#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007079#include <sys/statvfs.h>
7080
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007081static PyObject*
7082_pystatvfs_fromstructstatvfs(struct statvfs st) {
7083 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7084 if (v == NULL)
7085 return NULL;
7086
7087#if !defined(HAVE_LARGEFILE_SUPPORT)
7088 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7089 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7090 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7091 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7092 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7093 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7094 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7095 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7096 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7097 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7098#else
7099 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7100 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00007101 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007102 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00007103 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007104 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007105 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007106 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00007107 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007108 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00007109 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007110 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00007111 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007112 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007113 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7114 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7115#endif
7116
7117 return v;
7118}
7119
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007120PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007121"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007122Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007123
7124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007125posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007126{
7127 int fd, res;
7128 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007129
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007130 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007131 return NULL;
7132 Py_BEGIN_ALLOW_THREADS
7133 res = fstatvfs(fd, &st);
7134 Py_END_ALLOW_THREADS
7135 if (res != 0)
7136 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007137
7138 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007139}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007140#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007141
7142
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007143#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007144#include <sys/statvfs.h>
7145
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007146PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007147"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007148Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007149
7150static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007151posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007152{
7153 char *path;
7154 int res;
7155 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007156 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007157 return NULL;
7158 Py_BEGIN_ALLOW_THREADS
7159 res = statvfs(path, &st);
7160 Py_END_ALLOW_THREADS
7161 if (res != 0)
7162 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007163
7164 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007165}
7166#endif /* HAVE_STATVFS */
7167
7168
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007169#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007170PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007171"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007172Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007173The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007174or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007175
7176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007177posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007178{
7179 PyObject *result = NULL;
7180 char *dir = NULL;
7181 char *pfx = NULL;
7182 char *name;
7183
7184 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7185 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007186
7187 if (PyErr_Warn(PyExc_RuntimeWarning,
7188 "tempnam is a potential security risk to your program") < 0)
7189 return NULL;
7190
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007191#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007192 name = _tempnam(dir, pfx);
7193#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007194 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007195#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007196 if (name == NULL)
7197 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007198 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007199 free(name);
7200 return result;
7201}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007202#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007203
7204
7205#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007206PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007207"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007208Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007209
7210static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007211posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007212{
7213 FILE *fp;
7214
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007215 fp = tmpfile();
7216 if (fp == NULL)
7217 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007218 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007219}
7220#endif
7221
7222
7223#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007224PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007225"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007226Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007227
7228static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007229posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007230{
7231 char buffer[L_tmpnam];
7232 char *name;
7233
Skip Montanaro95618b52001-08-18 18:52:10 +00007234 if (PyErr_Warn(PyExc_RuntimeWarning,
7235 "tmpnam is a potential security risk to your program") < 0)
7236 return NULL;
7237
Greg Wardb48bc172000-03-01 21:51:56 +00007238#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007239 name = tmpnam_r(buffer);
7240#else
7241 name = tmpnam(buffer);
7242#endif
7243 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007244 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007245#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007246 "unexpected NULL from tmpnam_r"
7247#else
7248 "unexpected NULL from tmpnam"
7249#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007250 );
7251 PyErr_SetObject(PyExc_OSError, err);
7252 Py_XDECREF(err);
7253 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007254 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007255 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007256}
7257#endif
7258
7259
Fred Drakec9680921999-12-13 16:37:25 +00007260/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7261 * It maps strings representing configuration variable names to
7262 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007263 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007264 * rarely-used constants. There are three separate tables that use
7265 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007266 *
7267 * This code is always included, even if none of the interfaces that
7268 * need it are included. The #if hackery needed to avoid it would be
7269 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007270 */
7271struct constdef {
7272 char *name;
7273 long value;
7274};
7275
Fred Drake12c6e2d1999-12-14 21:25:03 +00007276static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007277conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7278 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007279{
7280 if (PyInt_Check(arg)) {
7281 *valuep = PyInt_AS_LONG(arg);
7282 return 1;
7283 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007284 if (PyString_Check(arg)) {
Fred Drake12c6e2d1999-12-14 21:25:03 +00007285 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00007286 size_t lo = 0;
7287 size_t mid;
7288 size_t hi = tablesize;
7289 int cmp;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007290 char *confname = PyString_AS_STRING(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007291 while (lo < hi) {
7292 mid = (lo + hi) / 2;
7293 cmp = strcmp(confname, table[mid].name);
7294 if (cmp < 0)
7295 hi = mid;
7296 else if (cmp > 0)
7297 lo = mid + 1;
7298 else {
7299 *valuep = table[mid].value;
7300 return 1;
7301 }
7302 }
7303 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7304 }
7305 else
7306 PyErr_SetString(PyExc_TypeError,
7307 "configuration names must be strings or integers");
7308 return 0;
7309}
7310
7311
7312#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7313static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007314#ifdef _PC_ABI_AIO_XFER_MAX
7315 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7316#endif
7317#ifdef _PC_ABI_ASYNC_IO
7318 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7319#endif
Fred Drakec9680921999-12-13 16:37:25 +00007320#ifdef _PC_ASYNC_IO
7321 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7322#endif
7323#ifdef _PC_CHOWN_RESTRICTED
7324 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7325#endif
7326#ifdef _PC_FILESIZEBITS
7327 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7328#endif
7329#ifdef _PC_LAST
7330 {"PC_LAST", _PC_LAST},
7331#endif
7332#ifdef _PC_LINK_MAX
7333 {"PC_LINK_MAX", _PC_LINK_MAX},
7334#endif
7335#ifdef _PC_MAX_CANON
7336 {"PC_MAX_CANON", _PC_MAX_CANON},
7337#endif
7338#ifdef _PC_MAX_INPUT
7339 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7340#endif
7341#ifdef _PC_NAME_MAX
7342 {"PC_NAME_MAX", _PC_NAME_MAX},
7343#endif
7344#ifdef _PC_NO_TRUNC
7345 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7346#endif
7347#ifdef _PC_PATH_MAX
7348 {"PC_PATH_MAX", _PC_PATH_MAX},
7349#endif
7350#ifdef _PC_PIPE_BUF
7351 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7352#endif
7353#ifdef _PC_PRIO_IO
7354 {"PC_PRIO_IO", _PC_PRIO_IO},
7355#endif
7356#ifdef _PC_SOCK_MAXBUF
7357 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7358#endif
7359#ifdef _PC_SYNC_IO
7360 {"PC_SYNC_IO", _PC_SYNC_IO},
7361#endif
7362#ifdef _PC_VDISABLE
7363 {"PC_VDISABLE", _PC_VDISABLE},
7364#endif
7365};
7366
Fred Drakec9680921999-12-13 16:37:25 +00007367static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007368conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007369{
7370 return conv_confname(arg, valuep, posix_constants_pathconf,
7371 sizeof(posix_constants_pathconf)
7372 / sizeof(struct constdef));
7373}
7374#endif
7375
7376#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007377PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007378"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007379Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007380If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007381
7382static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007383posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007384{
7385 PyObject *result = NULL;
7386 int name, fd;
7387
Fred Drake12c6e2d1999-12-14 21:25:03 +00007388 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7389 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00007390 long limit;
7391
7392 errno = 0;
7393 limit = fpathconf(fd, name);
7394 if (limit == -1 && errno != 0)
7395 posix_error();
7396 else
7397 result = PyInt_FromLong(limit);
7398 }
7399 return result;
7400}
7401#endif
7402
7403
7404#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007405PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007406"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007407Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007408If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007409
7410static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007411posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007412{
7413 PyObject *result = NULL;
7414 int name;
7415 char *path;
7416
7417 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7418 conv_path_confname, &name)) {
7419 long limit;
7420
7421 errno = 0;
7422 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007423 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00007424 if (errno == EINVAL)
7425 /* could be a path or name problem */
7426 posix_error();
7427 else
7428 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007429 }
Fred Drakec9680921999-12-13 16:37:25 +00007430 else
7431 result = PyInt_FromLong(limit);
7432 }
7433 return result;
7434}
7435#endif
7436
7437#ifdef HAVE_CONFSTR
7438static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007439#ifdef _CS_ARCHITECTURE
7440 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7441#endif
7442#ifdef _CS_HOSTNAME
7443 {"CS_HOSTNAME", _CS_HOSTNAME},
7444#endif
7445#ifdef _CS_HW_PROVIDER
7446 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7447#endif
7448#ifdef _CS_HW_SERIAL
7449 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7450#endif
7451#ifdef _CS_INITTAB_NAME
7452 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7453#endif
Fred Drakec9680921999-12-13 16:37:25 +00007454#ifdef _CS_LFS64_CFLAGS
7455 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7456#endif
7457#ifdef _CS_LFS64_LDFLAGS
7458 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7459#endif
7460#ifdef _CS_LFS64_LIBS
7461 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7462#endif
7463#ifdef _CS_LFS64_LINTFLAGS
7464 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7465#endif
7466#ifdef _CS_LFS_CFLAGS
7467 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7468#endif
7469#ifdef _CS_LFS_LDFLAGS
7470 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7471#endif
7472#ifdef _CS_LFS_LIBS
7473 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7474#endif
7475#ifdef _CS_LFS_LINTFLAGS
7476 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7477#endif
Fred Draked86ed291999-12-15 15:34:33 +00007478#ifdef _CS_MACHINE
7479 {"CS_MACHINE", _CS_MACHINE},
7480#endif
Fred Drakec9680921999-12-13 16:37:25 +00007481#ifdef _CS_PATH
7482 {"CS_PATH", _CS_PATH},
7483#endif
Fred Draked86ed291999-12-15 15:34:33 +00007484#ifdef _CS_RELEASE
7485 {"CS_RELEASE", _CS_RELEASE},
7486#endif
7487#ifdef _CS_SRPC_DOMAIN
7488 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7489#endif
7490#ifdef _CS_SYSNAME
7491 {"CS_SYSNAME", _CS_SYSNAME},
7492#endif
7493#ifdef _CS_VERSION
7494 {"CS_VERSION", _CS_VERSION},
7495#endif
Fred Drakec9680921999-12-13 16:37:25 +00007496#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7497 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7498#endif
7499#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7500 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7501#endif
7502#ifdef _CS_XBS5_ILP32_OFF32_LIBS
7503 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7504#endif
7505#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7506 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7507#endif
7508#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7509 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7510#endif
7511#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7512 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7513#endif
7514#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7515 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7516#endif
7517#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7518 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7519#endif
7520#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7521 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7522#endif
7523#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7524 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7525#endif
7526#ifdef _CS_XBS5_LP64_OFF64_LIBS
7527 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7528#endif
7529#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7530 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7531#endif
7532#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7533 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7534#endif
7535#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7536 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7537#endif
7538#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7539 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7540#endif
7541#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7542 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7543#endif
Fred Draked86ed291999-12-15 15:34:33 +00007544#ifdef _MIPS_CS_AVAIL_PROCESSORS
7545 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7546#endif
7547#ifdef _MIPS_CS_BASE
7548 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7549#endif
7550#ifdef _MIPS_CS_HOSTID
7551 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7552#endif
7553#ifdef _MIPS_CS_HW_NAME
7554 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7555#endif
7556#ifdef _MIPS_CS_NUM_PROCESSORS
7557 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7558#endif
7559#ifdef _MIPS_CS_OSREL_MAJ
7560 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7561#endif
7562#ifdef _MIPS_CS_OSREL_MIN
7563 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7564#endif
7565#ifdef _MIPS_CS_OSREL_PATCH
7566 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7567#endif
7568#ifdef _MIPS_CS_OS_NAME
7569 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7570#endif
7571#ifdef _MIPS_CS_OS_PROVIDER
7572 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7573#endif
7574#ifdef _MIPS_CS_PROCESSORS
7575 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7576#endif
7577#ifdef _MIPS_CS_SERIAL
7578 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7579#endif
7580#ifdef _MIPS_CS_VENDOR
7581 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7582#endif
Fred Drakec9680921999-12-13 16:37:25 +00007583};
7584
7585static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007586conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007587{
7588 return conv_confname(arg, valuep, posix_constants_confstr,
7589 sizeof(posix_constants_confstr)
7590 / sizeof(struct constdef));
7591}
7592
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007593PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007594"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007595Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007596
7597static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007598posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007599{
7600 PyObject *result = NULL;
7601 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007602 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007603
7604 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007605 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007606
Fred Drakec9680921999-12-13 16:37:25 +00007607 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007608 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007609 if (len == 0) {
7610 if (errno) {
7611 posix_error();
7612 }
7613 else {
7614 result = Py_None;
7615 Py_INCREF(Py_None);
7616 }
Fred Drakec9680921999-12-13 16:37:25 +00007617 }
7618 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007619 if ((unsigned int)len >= sizeof(buffer)) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007620 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007621 if (result != NULL)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007622 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007623 }
7624 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007625 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007626 }
7627 }
7628 return result;
7629}
7630#endif
7631
7632
7633#ifdef HAVE_SYSCONF
7634static struct constdef posix_constants_sysconf[] = {
7635#ifdef _SC_2_CHAR_TERM
7636 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7637#endif
7638#ifdef _SC_2_C_BIND
7639 {"SC_2_C_BIND", _SC_2_C_BIND},
7640#endif
7641#ifdef _SC_2_C_DEV
7642 {"SC_2_C_DEV", _SC_2_C_DEV},
7643#endif
7644#ifdef _SC_2_C_VERSION
7645 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7646#endif
7647#ifdef _SC_2_FORT_DEV
7648 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7649#endif
7650#ifdef _SC_2_FORT_RUN
7651 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7652#endif
7653#ifdef _SC_2_LOCALEDEF
7654 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7655#endif
7656#ifdef _SC_2_SW_DEV
7657 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7658#endif
7659#ifdef _SC_2_UPE
7660 {"SC_2_UPE", _SC_2_UPE},
7661#endif
7662#ifdef _SC_2_VERSION
7663 {"SC_2_VERSION", _SC_2_VERSION},
7664#endif
Fred Draked86ed291999-12-15 15:34:33 +00007665#ifdef _SC_ABI_ASYNCHRONOUS_IO
7666 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7667#endif
7668#ifdef _SC_ACL
7669 {"SC_ACL", _SC_ACL},
7670#endif
Fred Drakec9680921999-12-13 16:37:25 +00007671#ifdef _SC_AIO_LISTIO_MAX
7672 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7673#endif
Fred Drakec9680921999-12-13 16:37:25 +00007674#ifdef _SC_AIO_MAX
7675 {"SC_AIO_MAX", _SC_AIO_MAX},
7676#endif
7677#ifdef _SC_AIO_PRIO_DELTA_MAX
7678 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7679#endif
7680#ifdef _SC_ARG_MAX
7681 {"SC_ARG_MAX", _SC_ARG_MAX},
7682#endif
7683#ifdef _SC_ASYNCHRONOUS_IO
7684 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7685#endif
7686#ifdef _SC_ATEXIT_MAX
7687 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7688#endif
Fred Draked86ed291999-12-15 15:34:33 +00007689#ifdef _SC_AUDIT
7690 {"SC_AUDIT", _SC_AUDIT},
7691#endif
Fred Drakec9680921999-12-13 16:37:25 +00007692#ifdef _SC_AVPHYS_PAGES
7693 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7694#endif
7695#ifdef _SC_BC_BASE_MAX
7696 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7697#endif
7698#ifdef _SC_BC_DIM_MAX
7699 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7700#endif
7701#ifdef _SC_BC_SCALE_MAX
7702 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7703#endif
7704#ifdef _SC_BC_STRING_MAX
7705 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7706#endif
Fred Draked86ed291999-12-15 15:34:33 +00007707#ifdef _SC_CAP
7708 {"SC_CAP", _SC_CAP},
7709#endif
Fred Drakec9680921999-12-13 16:37:25 +00007710#ifdef _SC_CHARCLASS_NAME_MAX
7711 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7712#endif
7713#ifdef _SC_CHAR_BIT
7714 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7715#endif
7716#ifdef _SC_CHAR_MAX
7717 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7718#endif
7719#ifdef _SC_CHAR_MIN
7720 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7721#endif
7722#ifdef _SC_CHILD_MAX
7723 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7724#endif
7725#ifdef _SC_CLK_TCK
7726 {"SC_CLK_TCK", _SC_CLK_TCK},
7727#endif
7728#ifdef _SC_COHER_BLKSZ
7729 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7730#endif
7731#ifdef _SC_COLL_WEIGHTS_MAX
7732 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7733#endif
7734#ifdef _SC_DCACHE_ASSOC
7735 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7736#endif
7737#ifdef _SC_DCACHE_BLKSZ
7738 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7739#endif
7740#ifdef _SC_DCACHE_LINESZ
7741 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7742#endif
7743#ifdef _SC_DCACHE_SZ
7744 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7745#endif
7746#ifdef _SC_DCACHE_TBLKSZ
7747 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7748#endif
7749#ifdef _SC_DELAYTIMER_MAX
7750 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7751#endif
7752#ifdef _SC_EQUIV_CLASS_MAX
7753 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7754#endif
7755#ifdef _SC_EXPR_NEST_MAX
7756 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7757#endif
7758#ifdef _SC_FSYNC
7759 {"SC_FSYNC", _SC_FSYNC},
7760#endif
7761#ifdef _SC_GETGR_R_SIZE_MAX
7762 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7763#endif
7764#ifdef _SC_GETPW_R_SIZE_MAX
7765 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7766#endif
7767#ifdef _SC_ICACHE_ASSOC
7768 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7769#endif
7770#ifdef _SC_ICACHE_BLKSZ
7771 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7772#endif
7773#ifdef _SC_ICACHE_LINESZ
7774 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7775#endif
7776#ifdef _SC_ICACHE_SZ
7777 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7778#endif
Fred Draked86ed291999-12-15 15:34:33 +00007779#ifdef _SC_INF
7780 {"SC_INF", _SC_INF},
7781#endif
Fred Drakec9680921999-12-13 16:37:25 +00007782#ifdef _SC_INT_MAX
7783 {"SC_INT_MAX", _SC_INT_MAX},
7784#endif
7785#ifdef _SC_INT_MIN
7786 {"SC_INT_MIN", _SC_INT_MIN},
7787#endif
7788#ifdef _SC_IOV_MAX
7789 {"SC_IOV_MAX", _SC_IOV_MAX},
7790#endif
Fred Draked86ed291999-12-15 15:34:33 +00007791#ifdef _SC_IP_SECOPTS
7792 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7793#endif
Fred Drakec9680921999-12-13 16:37:25 +00007794#ifdef _SC_JOB_CONTROL
7795 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7796#endif
Fred Draked86ed291999-12-15 15:34:33 +00007797#ifdef _SC_KERN_POINTERS
7798 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7799#endif
7800#ifdef _SC_KERN_SIM
7801 {"SC_KERN_SIM", _SC_KERN_SIM},
7802#endif
Fred Drakec9680921999-12-13 16:37:25 +00007803#ifdef _SC_LINE_MAX
7804 {"SC_LINE_MAX", _SC_LINE_MAX},
7805#endif
7806#ifdef _SC_LOGIN_NAME_MAX
7807 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7808#endif
7809#ifdef _SC_LOGNAME_MAX
7810 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7811#endif
7812#ifdef _SC_LONG_BIT
7813 {"SC_LONG_BIT", _SC_LONG_BIT},
7814#endif
Fred Draked86ed291999-12-15 15:34:33 +00007815#ifdef _SC_MAC
7816 {"SC_MAC", _SC_MAC},
7817#endif
Fred Drakec9680921999-12-13 16:37:25 +00007818#ifdef _SC_MAPPED_FILES
7819 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7820#endif
7821#ifdef _SC_MAXPID
7822 {"SC_MAXPID", _SC_MAXPID},
7823#endif
7824#ifdef _SC_MB_LEN_MAX
7825 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7826#endif
7827#ifdef _SC_MEMLOCK
7828 {"SC_MEMLOCK", _SC_MEMLOCK},
7829#endif
7830#ifdef _SC_MEMLOCK_RANGE
7831 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7832#endif
7833#ifdef _SC_MEMORY_PROTECTION
7834 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7835#endif
7836#ifdef _SC_MESSAGE_PASSING
7837 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7838#endif
Fred Draked86ed291999-12-15 15:34:33 +00007839#ifdef _SC_MMAP_FIXED_ALIGNMENT
7840 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7841#endif
Fred Drakec9680921999-12-13 16:37:25 +00007842#ifdef _SC_MQ_OPEN_MAX
7843 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7844#endif
7845#ifdef _SC_MQ_PRIO_MAX
7846 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7847#endif
Fred Draked86ed291999-12-15 15:34:33 +00007848#ifdef _SC_NACLS_MAX
7849 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7850#endif
Fred Drakec9680921999-12-13 16:37:25 +00007851#ifdef _SC_NGROUPS_MAX
7852 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7853#endif
7854#ifdef _SC_NL_ARGMAX
7855 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7856#endif
7857#ifdef _SC_NL_LANGMAX
7858 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7859#endif
7860#ifdef _SC_NL_MSGMAX
7861 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7862#endif
7863#ifdef _SC_NL_NMAX
7864 {"SC_NL_NMAX", _SC_NL_NMAX},
7865#endif
7866#ifdef _SC_NL_SETMAX
7867 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7868#endif
7869#ifdef _SC_NL_TEXTMAX
7870 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7871#endif
7872#ifdef _SC_NPROCESSORS_CONF
7873 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7874#endif
7875#ifdef _SC_NPROCESSORS_ONLN
7876 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7877#endif
Fred Draked86ed291999-12-15 15:34:33 +00007878#ifdef _SC_NPROC_CONF
7879 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7880#endif
7881#ifdef _SC_NPROC_ONLN
7882 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7883#endif
Fred Drakec9680921999-12-13 16:37:25 +00007884#ifdef _SC_NZERO
7885 {"SC_NZERO", _SC_NZERO},
7886#endif
7887#ifdef _SC_OPEN_MAX
7888 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7889#endif
7890#ifdef _SC_PAGESIZE
7891 {"SC_PAGESIZE", _SC_PAGESIZE},
7892#endif
7893#ifdef _SC_PAGE_SIZE
7894 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7895#endif
7896#ifdef _SC_PASS_MAX
7897 {"SC_PASS_MAX", _SC_PASS_MAX},
7898#endif
7899#ifdef _SC_PHYS_PAGES
7900 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7901#endif
7902#ifdef _SC_PII
7903 {"SC_PII", _SC_PII},
7904#endif
7905#ifdef _SC_PII_INTERNET
7906 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7907#endif
7908#ifdef _SC_PII_INTERNET_DGRAM
7909 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7910#endif
7911#ifdef _SC_PII_INTERNET_STREAM
7912 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7913#endif
7914#ifdef _SC_PII_OSI
7915 {"SC_PII_OSI", _SC_PII_OSI},
7916#endif
7917#ifdef _SC_PII_OSI_CLTS
7918 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7919#endif
7920#ifdef _SC_PII_OSI_COTS
7921 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7922#endif
7923#ifdef _SC_PII_OSI_M
7924 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7925#endif
7926#ifdef _SC_PII_SOCKET
7927 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7928#endif
7929#ifdef _SC_PII_XTI
7930 {"SC_PII_XTI", _SC_PII_XTI},
7931#endif
7932#ifdef _SC_POLL
7933 {"SC_POLL", _SC_POLL},
7934#endif
7935#ifdef _SC_PRIORITIZED_IO
7936 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7937#endif
7938#ifdef _SC_PRIORITY_SCHEDULING
7939 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7940#endif
7941#ifdef _SC_REALTIME_SIGNALS
7942 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7943#endif
7944#ifdef _SC_RE_DUP_MAX
7945 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7946#endif
7947#ifdef _SC_RTSIG_MAX
7948 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7949#endif
7950#ifdef _SC_SAVED_IDS
7951 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7952#endif
7953#ifdef _SC_SCHAR_MAX
7954 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7955#endif
7956#ifdef _SC_SCHAR_MIN
7957 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7958#endif
7959#ifdef _SC_SELECT
7960 {"SC_SELECT", _SC_SELECT},
7961#endif
7962#ifdef _SC_SEMAPHORES
7963 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7964#endif
7965#ifdef _SC_SEM_NSEMS_MAX
7966 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7967#endif
7968#ifdef _SC_SEM_VALUE_MAX
7969 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7970#endif
7971#ifdef _SC_SHARED_MEMORY_OBJECTS
7972 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7973#endif
7974#ifdef _SC_SHRT_MAX
7975 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7976#endif
7977#ifdef _SC_SHRT_MIN
7978 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7979#endif
7980#ifdef _SC_SIGQUEUE_MAX
7981 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7982#endif
7983#ifdef _SC_SIGRT_MAX
7984 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7985#endif
7986#ifdef _SC_SIGRT_MIN
7987 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7988#endif
Fred Draked86ed291999-12-15 15:34:33 +00007989#ifdef _SC_SOFTPOWER
7990 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7991#endif
Fred Drakec9680921999-12-13 16:37:25 +00007992#ifdef _SC_SPLIT_CACHE
7993 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7994#endif
7995#ifdef _SC_SSIZE_MAX
7996 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7997#endif
7998#ifdef _SC_STACK_PROT
7999 {"SC_STACK_PROT", _SC_STACK_PROT},
8000#endif
8001#ifdef _SC_STREAM_MAX
8002 {"SC_STREAM_MAX", _SC_STREAM_MAX},
8003#endif
8004#ifdef _SC_SYNCHRONIZED_IO
8005 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
8006#endif
8007#ifdef _SC_THREADS
8008 {"SC_THREADS", _SC_THREADS},
8009#endif
8010#ifdef _SC_THREAD_ATTR_STACKADDR
8011 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
8012#endif
8013#ifdef _SC_THREAD_ATTR_STACKSIZE
8014 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
8015#endif
8016#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
8017 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
8018#endif
8019#ifdef _SC_THREAD_KEYS_MAX
8020 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
8021#endif
8022#ifdef _SC_THREAD_PRIORITY_SCHEDULING
8023 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
8024#endif
8025#ifdef _SC_THREAD_PRIO_INHERIT
8026 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
8027#endif
8028#ifdef _SC_THREAD_PRIO_PROTECT
8029 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
8030#endif
8031#ifdef _SC_THREAD_PROCESS_SHARED
8032 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
8033#endif
8034#ifdef _SC_THREAD_SAFE_FUNCTIONS
8035 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
8036#endif
8037#ifdef _SC_THREAD_STACK_MIN
8038 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
8039#endif
8040#ifdef _SC_THREAD_THREADS_MAX
8041 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
8042#endif
8043#ifdef _SC_TIMERS
8044 {"SC_TIMERS", _SC_TIMERS},
8045#endif
8046#ifdef _SC_TIMER_MAX
8047 {"SC_TIMER_MAX", _SC_TIMER_MAX},
8048#endif
8049#ifdef _SC_TTY_NAME_MAX
8050 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
8051#endif
8052#ifdef _SC_TZNAME_MAX
8053 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
8054#endif
8055#ifdef _SC_T_IOV_MAX
8056 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
8057#endif
8058#ifdef _SC_UCHAR_MAX
8059 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
8060#endif
8061#ifdef _SC_UINT_MAX
8062 {"SC_UINT_MAX", _SC_UINT_MAX},
8063#endif
8064#ifdef _SC_UIO_MAXIOV
8065 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
8066#endif
8067#ifdef _SC_ULONG_MAX
8068 {"SC_ULONG_MAX", _SC_ULONG_MAX},
8069#endif
8070#ifdef _SC_USHRT_MAX
8071 {"SC_USHRT_MAX", _SC_USHRT_MAX},
8072#endif
8073#ifdef _SC_VERSION
8074 {"SC_VERSION", _SC_VERSION},
8075#endif
8076#ifdef _SC_WORD_BIT
8077 {"SC_WORD_BIT", _SC_WORD_BIT},
8078#endif
8079#ifdef _SC_XBS5_ILP32_OFF32
8080 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
8081#endif
8082#ifdef _SC_XBS5_ILP32_OFFBIG
8083 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
8084#endif
8085#ifdef _SC_XBS5_LP64_OFF64
8086 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
8087#endif
8088#ifdef _SC_XBS5_LPBIG_OFFBIG
8089 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
8090#endif
8091#ifdef _SC_XOPEN_CRYPT
8092 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
8093#endif
8094#ifdef _SC_XOPEN_ENH_I18N
8095 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
8096#endif
8097#ifdef _SC_XOPEN_LEGACY
8098 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
8099#endif
8100#ifdef _SC_XOPEN_REALTIME
8101 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
8102#endif
8103#ifdef _SC_XOPEN_REALTIME_THREADS
8104 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
8105#endif
8106#ifdef _SC_XOPEN_SHM
8107 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
8108#endif
8109#ifdef _SC_XOPEN_UNIX
8110 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
8111#endif
8112#ifdef _SC_XOPEN_VERSION
8113 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
8114#endif
8115#ifdef _SC_XOPEN_XCU_VERSION
8116 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
8117#endif
8118#ifdef _SC_XOPEN_XPG2
8119 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
8120#endif
8121#ifdef _SC_XOPEN_XPG3
8122 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
8123#endif
8124#ifdef _SC_XOPEN_XPG4
8125 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
8126#endif
8127};
8128
8129static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008130conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008131{
8132 return conv_confname(arg, valuep, posix_constants_sysconf,
8133 sizeof(posix_constants_sysconf)
8134 / sizeof(struct constdef));
8135}
8136
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008137PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008138"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008139Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008140
8141static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008142posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008143{
8144 PyObject *result = NULL;
8145 int name;
8146
8147 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
8148 int value;
8149
8150 errno = 0;
8151 value = sysconf(name);
8152 if (value == -1 && errno != 0)
8153 posix_error();
8154 else
8155 result = PyInt_FromLong(value);
8156 }
8157 return result;
8158}
8159#endif
8160
8161
Fred Drakebec628d1999-12-15 18:31:10 +00008162/* This code is used to ensure that the tables of configuration value names
8163 * are in sorted order as required by conv_confname(), and also to build the
8164 * the exported dictionaries that are used to publish information about the
8165 * names available on the host platform.
8166 *
8167 * Sorting the table at runtime ensures that the table is properly ordered
8168 * when used, even for platforms we're not able to test on. It also makes
8169 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008170 */
Fred Drakebec628d1999-12-15 18:31:10 +00008171
8172static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008173cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008174{
8175 const struct constdef *c1 =
8176 (const struct constdef *) v1;
8177 const struct constdef *c2 =
8178 (const struct constdef *) v2;
8179
8180 return strcmp(c1->name, c2->name);
8181}
8182
8183static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008184setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008185 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008186{
Fred Drakebec628d1999-12-15 18:31:10 +00008187 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008188 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008189
8190 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8191 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008192 if (d == NULL)
8193 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008194
Barry Warsaw3155db32000-04-13 15:20:40 +00008195 for (i=0; i < tablesize; ++i) {
8196 PyObject *o = PyInt_FromLong(table[i].value);
8197 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8198 Py_XDECREF(o);
8199 Py_DECREF(d);
8200 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008201 }
Barry Warsaw3155db32000-04-13 15:20:40 +00008202 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008203 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008204 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008205}
8206
Fred Drakebec628d1999-12-15 18:31:10 +00008207/* Return -1 on failure, 0 on success. */
8208static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008209setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008210{
8211#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008212 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008213 sizeof(posix_constants_pathconf)
8214 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008215 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008216 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008217#endif
8218#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008219 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008220 sizeof(posix_constants_confstr)
8221 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008222 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008223 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008224#endif
8225#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008226 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008227 sizeof(posix_constants_sysconf)
8228 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008229 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008230 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008231#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008232 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008233}
Fred Draked86ed291999-12-15 15:34:33 +00008234
8235
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008236PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008237"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008238Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008239in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008240
8241static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008242posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008243{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008244 abort();
8245 /*NOTREACHED*/
8246 Py_FatalError("abort() called from Python code didn't abort!");
8247 return NULL;
8248}
Fred Drakebec628d1999-12-15 18:31:10 +00008249
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008250#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008251PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008252"startfile(filepath [, operation]) - Start a file with its associated\n\
8253application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008254\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008255When \"operation\" is not specified or \"open\", this acts like\n\
8256double-clicking the file in Explorer, or giving the file name as an\n\
8257argument to the DOS \"start\" command: the file is opened with whatever\n\
8258application (if any) its extension is associated.\n\
8259When another \"operation\" is given, it specifies what should be done with\n\
8260the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008261\n\
8262startfile returns as soon as the associated application is launched.\n\
8263There is no option to wait for the application to close, and no way\n\
8264to retrieve the application's exit status.\n\
8265\n\
8266The filepath is relative to the current directory. If you want to use\n\
8267an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008268the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008269
8270static PyObject *
8271win32_startfile(PyObject *self, PyObject *args)
8272{
8273 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00008274 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008275 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00008276#ifdef Py_WIN_WIDE_FILENAMES
8277 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008278 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00008279 if (!PyArg_ParseTuple(args, "U|s:startfile",
8280 &unipath, &operation)) {
8281 PyErr_Clear();
8282 goto normal;
8283 }
8284
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008285
8286 if (operation) {
8287 woperation = PyUnicode_DecodeASCII(operation,
8288 strlen(operation), NULL);
8289 if (!woperation) {
8290 PyErr_Clear();
8291 operation = NULL;
8292 goto normal;
8293 }
Georg Brandlad89dc82006-04-03 12:26:26 +00008294 }
8295
8296 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008297 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00008298 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00008299 NULL, NULL, SW_SHOWNORMAL);
8300 Py_END_ALLOW_THREADS
8301
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008302 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00008303 if (rc <= (HINSTANCE)32) {
8304 PyObject *errval = win32_error_unicode("startfile",
8305 PyUnicode_AS_UNICODE(unipath));
8306 return errval;
8307 }
8308 Py_INCREF(Py_None);
8309 return Py_None;
8310 }
8311#endif
8312
8313normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00008314 if (!PyArg_ParseTuple(args, "et|s:startfile",
8315 Py_FileSystemDefaultEncoding, &filepath,
8316 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00008317 return NULL;
8318 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00008319 rc = ShellExecute((HWND)0, operation, filepath,
8320 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008321 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00008322 if (rc <= (HINSTANCE)32) {
8323 PyObject *errval = win32_error("startfile", filepath);
8324 PyMem_Free(filepath);
8325 return errval;
8326 }
8327 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008328 Py_INCREF(Py_None);
8329 return Py_None;
8330}
8331#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008332
Martin v. Löwis438b5342002-12-27 10:16:42 +00008333#ifdef HAVE_GETLOADAVG
8334PyDoc_STRVAR(posix_getloadavg__doc__,
8335"getloadavg() -> (float, float, float)\n\n\
8336Return the number of processes in the system run queue averaged over\n\
8337the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8338was unobtainable");
8339
8340static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008341posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008342{
8343 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008344 if (getloadavg(loadavg, 3)!=3) {
8345 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8346 return NULL;
8347 } else
8348 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8349}
8350#endif
8351
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008352#ifdef MS_WINDOWS
8353
8354PyDoc_STRVAR(win32_urandom__doc__,
8355"urandom(n) -> str\n\n\
8356Return a string of n random bytes suitable for cryptographic use.");
8357
8358typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8359 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8360 DWORD dwFlags );
8361typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8362 BYTE *pbBuffer );
8363
8364static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008365/* This handle is never explicitly released. Instead, the operating
8366 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008367static HCRYPTPROV hCryptProv = 0;
8368
Tim Peters4ad82172004-08-30 17:02:04 +00008369static PyObject*
8370win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008371{
Tim Petersd3115382004-08-30 17:36:46 +00008372 int howMany;
8373 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008374
Tim Peters4ad82172004-08-30 17:02:04 +00008375 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00008376 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00008377 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00008378 if (howMany < 0)
8379 return PyErr_Format(PyExc_ValueError,
8380 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008381
Tim Peters4ad82172004-08-30 17:02:04 +00008382 if (hCryptProv == 0) {
8383 HINSTANCE hAdvAPI32 = NULL;
8384 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008385
Tim Peters4ad82172004-08-30 17:02:04 +00008386 /* Obtain handle to the DLL containing CryptoAPI
8387 This should not fail */
8388 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8389 if(hAdvAPI32 == NULL)
8390 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008391
Tim Peters4ad82172004-08-30 17:02:04 +00008392 /* Obtain pointers to the CryptoAPI functions
8393 This will fail on some early versions of Win95 */
8394 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8395 hAdvAPI32,
8396 "CryptAcquireContextA");
8397 if (pCryptAcquireContext == NULL)
8398 return PyErr_Format(PyExc_NotImplementedError,
8399 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008400
Tim Peters4ad82172004-08-30 17:02:04 +00008401 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8402 hAdvAPI32, "CryptGenRandom");
Georg Brandl74bb7832006-09-06 06:03:59 +00008403 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00008404 return PyErr_Format(PyExc_NotImplementedError,
8405 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008406
Tim Peters4ad82172004-08-30 17:02:04 +00008407 /* Acquire context */
8408 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8409 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8410 return win32_error("CryptAcquireContext", NULL);
8411 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008412
Tim Peters4ad82172004-08-30 17:02:04 +00008413 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008414 result = PyString_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00008415 if (result != NULL) {
8416 /* Get random data */
Amaury Forgeot d'Arc74bd40d2008-07-21 21:06:46 +00008417 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00008418 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008419 PyString_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00008420 Py_DECREF(result);
8421 return win32_error("CryptGenRandom", NULL);
8422 }
Tim Peters4ad82172004-08-30 17:02:04 +00008423 }
Tim Petersd3115382004-08-30 17:36:46 +00008424 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008425}
8426#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008427
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008428#ifdef __VMS
8429/* Use openssl random routine */
8430#include <openssl/rand.h>
8431PyDoc_STRVAR(vms_urandom__doc__,
8432"urandom(n) -> str\n\n\
8433Return a string of n random bytes suitable for cryptographic use.");
8434
8435static PyObject*
8436vms_urandom(PyObject *self, PyObject *args)
8437{
8438 int howMany;
8439 PyObject* result;
8440
8441 /* Read arguments */
8442 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8443 return NULL;
8444 if (howMany < 0)
8445 return PyErr_Format(PyExc_ValueError,
8446 "negative argument not allowed");
8447
8448 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008449 result = PyString_FromStringAndSize(NULL, howMany);
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008450 if (result != NULL) {
8451 /* Get random data */
8452 if (RAND_pseudo_bytes((unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008453 PyString_AS_STRING(result),
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008454 howMany) < 0) {
8455 Py_DECREF(result);
8456 return PyErr_Format(PyExc_ValueError,
8457 "RAND_pseudo_bytes");
8458 }
8459 }
8460 return result;
8461}
8462#endif
8463
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008464static PyMethodDef posix_methods[] = {
8465 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8466#ifdef HAVE_TTYNAME
8467 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8468#endif
8469 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008470#ifdef HAVE_CHFLAGS
8471 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8472#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008473 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008474#ifdef HAVE_FCHMOD
8475 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8476#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008477#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008478 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008479#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008480#ifdef HAVE_LCHMOD
8481 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8482#endif /* HAVE_LCHMOD */
8483#ifdef HAVE_FCHOWN
8484 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8485#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008486#ifdef HAVE_LCHFLAGS
8487 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8488#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008489#ifdef HAVE_LCHOWN
8490 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8491#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008492#ifdef HAVE_CHROOT
8493 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8494#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008495#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00008496 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008497#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008498#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00008499 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008500#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00008501 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008502#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008503#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008504#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008505 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008506#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008507 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8508 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8509 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008510#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008511 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008512#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008513#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008514 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008515#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008516 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8517 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8518 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008519 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008520#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008521 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008522#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008523#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008524 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008525#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008526 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008527#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00008528 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008529#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008530 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8531 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8532 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008533#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00008534 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008535#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008536 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008537#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008538 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8539 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008540#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008541#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008542 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8543 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008544#if defined(PYOS_OS2)
8545 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8546 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8547#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008548#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008549#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008550 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008551#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008552#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008553 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008554#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008555#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008556 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008557#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008558#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008559 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008560#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008561#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008562 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008563#endif /* HAVE_GETEGID */
8564#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008565 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008566#endif /* HAVE_GETEUID */
8567#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008568 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008569#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008570#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008571 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008572#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008573 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008574#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008575 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008576#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008577#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008578 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008579#endif /* HAVE_GETPPID */
8580#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008581 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008582#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008583#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008584 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008585#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008586#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008587 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008588#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008589#ifdef HAVE_KILLPG
8590 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8591#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008592#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008593 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008594#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008595#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008596 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008597#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008598 {"popen2", win32_popen2, METH_VARARGS},
8599 {"popen3", win32_popen3, METH_VARARGS},
8600 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008601 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008602#else
8603#if defined(PYOS_OS2) && defined(PYCC_GCC)
8604 {"popen2", os2emx_popen2, METH_VARARGS},
8605 {"popen3", os2emx_popen3, METH_VARARGS},
8606 {"popen4", os2emx_popen4, METH_VARARGS},
8607#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008608#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008609#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008610#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008611 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008612#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008613#ifdef HAVE_SETEUID
8614 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8615#endif /* HAVE_SETEUID */
8616#ifdef HAVE_SETEGID
8617 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8618#endif /* HAVE_SETEGID */
8619#ifdef HAVE_SETREUID
8620 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8621#endif /* HAVE_SETREUID */
8622#ifdef HAVE_SETREGID
8623 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8624#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008625#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008626 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008627#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008628#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008629 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008630#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008631#ifdef HAVE_GETPGID
8632 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8633#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008634#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008635 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008636#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008637#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008638 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008639#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008640#ifdef HAVE_WAIT3
8641 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8642#endif /* HAVE_WAIT3 */
8643#ifdef HAVE_WAIT4
8644 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8645#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008646#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008647 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008648#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008649#ifdef HAVE_GETSID
8650 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8651#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008652#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008653 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008654#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008655#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008656 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008657#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008658#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008659 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008660#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008661#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008662 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008663#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008664 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8665 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Georg Brandl309501a2008-01-19 20:22:13 +00008666 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008667 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8668 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8669 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8670 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8671 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8672 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8673 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008674 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008675#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008676 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008677#endif
8678#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008679 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008680#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008681#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008682 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8683#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008684#ifdef HAVE_DEVICE_MACROS
8685 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8686 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8687 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8688#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008689#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008690 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008691#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008692#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008693 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008694#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008695#ifdef HAVE_UNSETENV
8696 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8697#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008698 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008699#ifdef HAVE_FCHDIR
8700 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8701#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008702#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008703 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008704#endif
8705#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008706 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008707#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008708#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008709#ifdef WCOREDUMP
8710 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8711#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008712#ifdef WIFCONTINUED
8713 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8714#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008715#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008716 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008717#endif /* WIFSTOPPED */
8718#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008719 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008720#endif /* WIFSIGNALED */
8721#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008722 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008723#endif /* WIFEXITED */
8724#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008725 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008726#endif /* WEXITSTATUS */
8727#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008728 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008729#endif /* WTERMSIG */
8730#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008731 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008732#endif /* WSTOPSIG */
8733#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008734#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008735 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008736#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008737#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008738 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008739#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008740#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008741 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008742#endif
8743#ifdef HAVE_TEMPNAM
8744 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8745#endif
8746#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008747 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008748#endif
Fred Drakec9680921999-12-13 16:37:25 +00008749#ifdef HAVE_CONFSTR
8750 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8751#endif
8752#ifdef HAVE_SYSCONF
8753 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8754#endif
8755#ifdef HAVE_FPATHCONF
8756 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8757#endif
8758#ifdef HAVE_PATHCONF
8759 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8760#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008761 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008762#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008763 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8764#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008765#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008766 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008767#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008768 #ifdef MS_WINDOWS
8769 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8770 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008771 #ifdef __VMS
8772 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8773 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008774 {NULL, NULL} /* Sentinel */
8775};
8776
8777
Barry Warsaw4a342091996-12-19 23:50:02 +00008778static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008779ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008780{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008781 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008782}
8783
Guido van Rossumd48f2521997-12-05 22:19:34 +00008784#if defined(PYOS_OS2)
8785/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008786static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008787{
8788 APIRET rc;
8789 ULONG values[QSV_MAX+1];
8790 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008791 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008792
8793 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008794 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008795 Py_END_ALLOW_THREADS
8796
8797 if (rc != NO_ERROR) {
8798 os2_error(rc);
8799 return -1;
8800 }
8801
Fred Drake4d1e64b2002-04-15 19:40:07 +00008802 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8803 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8804 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8805 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8806 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8807 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8808 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008809
8810 switch (values[QSV_VERSION_MINOR]) {
8811 case 0: ver = "2.00"; break;
8812 case 10: ver = "2.10"; break;
8813 case 11: ver = "2.11"; break;
8814 case 30: ver = "3.00"; break;
8815 case 40: ver = "4.00"; break;
8816 case 50: ver = "5.00"; break;
8817 default:
Tim Peters885d4572001-11-28 20:27:42 +00008818 PyOS_snprintf(tmp, sizeof(tmp),
8819 "%d-%d", values[QSV_VERSION_MAJOR],
8820 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008821 ver = &tmp[0];
8822 }
8823
8824 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008825 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008826 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008827
8828 /* Add Indicator of Which Drive was Used to Boot the System */
8829 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8830 tmp[1] = ':';
8831 tmp[2] = '\0';
8832
Fred Drake4d1e64b2002-04-15 19:40:07 +00008833 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008834}
8835#endif
8836
Barry Warsaw4a342091996-12-19 23:50:02 +00008837static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008838all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008839{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008840#ifdef F_OK
8841 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008842#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008843#ifdef R_OK
8844 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008845#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008846#ifdef W_OK
8847 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008848#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008849#ifdef X_OK
8850 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008851#endif
Fred Drakec9680921999-12-13 16:37:25 +00008852#ifdef NGROUPS_MAX
8853 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8854#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008855#ifdef TMP_MAX
8856 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8857#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008858#ifdef WCONTINUED
8859 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8860#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008861#ifdef WNOHANG
8862 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008863#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008864#ifdef WUNTRACED
8865 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8866#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008867#ifdef O_RDONLY
8868 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8869#endif
8870#ifdef O_WRONLY
8871 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8872#endif
8873#ifdef O_RDWR
8874 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8875#endif
8876#ifdef O_NDELAY
8877 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8878#endif
8879#ifdef O_NONBLOCK
8880 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8881#endif
8882#ifdef O_APPEND
8883 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8884#endif
8885#ifdef O_DSYNC
8886 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8887#endif
8888#ifdef O_RSYNC
8889 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8890#endif
8891#ifdef O_SYNC
8892 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8893#endif
8894#ifdef O_NOCTTY
8895 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8896#endif
8897#ifdef O_CREAT
8898 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8899#endif
8900#ifdef O_EXCL
8901 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8902#endif
8903#ifdef O_TRUNC
8904 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8905#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008906#ifdef O_BINARY
8907 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8908#endif
8909#ifdef O_TEXT
8910 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8911#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008912#ifdef O_LARGEFILE
8913 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8914#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008915#ifdef O_SHLOCK
8916 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8917#endif
8918#ifdef O_EXLOCK
8919 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8920#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008921
Tim Peters5aa91602002-01-30 05:46:57 +00008922/* MS Windows */
8923#ifdef O_NOINHERIT
8924 /* Don't inherit in child processes. */
8925 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8926#endif
8927#ifdef _O_SHORT_LIVED
8928 /* Optimize for short life (keep in memory). */
8929 /* MS forgot to define this one with a non-underscore form too. */
8930 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8931#endif
8932#ifdef O_TEMPORARY
8933 /* Automatically delete when last handle is closed. */
8934 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8935#endif
8936#ifdef O_RANDOM
8937 /* Optimize for random access. */
8938 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8939#endif
8940#ifdef O_SEQUENTIAL
8941 /* Optimize for sequential access. */
8942 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8943#endif
8944
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008945/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00008946#ifdef O_ASYNC
8947 /* Send a SIGIO signal whenever input or output
8948 becomes available on file descriptor */
8949 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8950#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008951#ifdef O_DIRECT
8952 /* Direct disk access. */
8953 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8954#endif
8955#ifdef O_DIRECTORY
8956 /* Must be a directory. */
8957 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8958#endif
8959#ifdef O_NOFOLLOW
8960 /* Do not follow links. */
8961 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8962#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00008963#ifdef O_NOATIME
8964 /* Do not update the access time. */
8965 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8966#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008967
Barry Warsaw5676bd12003-01-07 20:57:09 +00008968 /* These come from sysexits.h */
8969#ifdef EX_OK
8970 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008971#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008972#ifdef EX_USAGE
8973 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008974#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008975#ifdef EX_DATAERR
8976 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008977#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008978#ifdef EX_NOINPUT
8979 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008980#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008981#ifdef EX_NOUSER
8982 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008983#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008984#ifdef EX_NOHOST
8985 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008986#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008987#ifdef EX_UNAVAILABLE
8988 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008989#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008990#ifdef EX_SOFTWARE
8991 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008992#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008993#ifdef EX_OSERR
8994 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008995#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008996#ifdef EX_OSFILE
8997 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008998#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008999#ifdef EX_CANTCREAT
9000 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009001#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009002#ifdef EX_IOERR
9003 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009004#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009005#ifdef EX_TEMPFAIL
9006 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009007#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009008#ifdef EX_PROTOCOL
9009 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009010#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009011#ifdef EX_NOPERM
9012 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009013#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009014#ifdef EX_CONFIG
9015 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009016#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009017#ifdef EX_NOTFOUND
9018 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009019#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009020
Guido van Rossum246bc171999-02-01 23:54:31 +00009021#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009022#if defined(PYOS_OS2) && defined(PYCC_GCC)
9023 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9024 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9025 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9026 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9027 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9028 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9029 if (ins(d, "P_PM", (long)P_PM)) return -1;
9030 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9031 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9032 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9033 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9034 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9035 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9036 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9037 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9038 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9039 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9040 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9041 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9042 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
9043#else
Guido van Rossum7d385291999-02-16 19:38:04 +00009044 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9045 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9046 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9047 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9048 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009049#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009050#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009051
Guido van Rossumd48f2521997-12-05 22:19:34 +00009052#if defined(PYOS_OS2)
9053 if (insertvalues(d)) return -1;
9054#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009055 return 0;
9056}
9057
9058
Tim Peters5aa91602002-01-30 05:46:57 +00009059#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009060#define INITFUNC initnt
9061#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009062
9063#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009064#define INITFUNC initos2
9065#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009066
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009067#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009068#define INITFUNC initposix
9069#define MODNAME "posix"
9070#endif
9071
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009072PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009073INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009074{
Fred Drake4d1e64b2002-04-15 19:40:07 +00009075 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009076
Fred Drake4d1e64b2002-04-15 19:40:07 +00009077 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009078 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00009079 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00009080 if (m == NULL)
9081 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009082
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009083 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009084 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00009085 Py_XINCREF(v);
9086 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009087 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00009088 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009089
Fred Drake4d1e64b2002-04-15 19:40:07 +00009090 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00009091 return;
9092
Fred Drake4d1e64b2002-04-15 19:40:07 +00009093 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00009094 return;
9095
Fred Drake4d1e64b2002-04-15 19:40:07 +00009096 Py_INCREF(PyExc_OSError);
9097 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009098
Guido van Rossumb3d39562000-01-31 18:41:26 +00009099#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00009100 if (posix_putenv_garbage == NULL)
9101 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009102#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009103
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009104 if (!initialized) {
9105 stat_result_desc.name = MODNAME ".stat_result";
9106 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9107 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9108 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9109 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9110 structseq_new = StatResultType.tp_new;
9111 StatResultType.tp_new = statresult_new;
9112
9113 statvfs_result_desc.name = MODNAME ".statvfs_result";
9114 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009115#ifdef NEED_TICKS_PER_SECOND
9116# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
9117 ticks_per_second = sysconf(_SC_CLK_TCK);
9118# elif defined(HZ)
9119 ticks_per_second = HZ;
9120# else
9121 ticks_per_second = 60; /* magic fallback value; may be bogus */
9122# endif
9123#endif
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009124 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009125 Py_INCREF((PyObject*) &StatResultType);
9126 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00009127 Py_INCREF((PyObject*) &StatVFSResultType);
9128 PyModule_AddObject(m, "statvfs_result",
9129 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009130 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009131
9132#ifdef __APPLE__
9133 /*
9134 * Step 2 of weak-linking support on Mac OS X.
9135 *
9136 * The code below removes functions that are not available on the
9137 * currently active platform.
9138 *
9139 * This block allow one to use a python binary that was build on
9140 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9141 * OSX 10.4.
9142 */
9143#ifdef HAVE_FSTATVFS
9144 if (fstatvfs == NULL) {
9145 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9146 return;
9147 }
9148 }
9149#endif /* HAVE_FSTATVFS */
9150
9151#ifdef HAVE_STATVFS
9152 if (statvfs == NULL) {
9153 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9154 return;
9155 }
9156 }
9157#endif /* HAVE_STATVFS */
9158
9159# ifdef HAVE_LCHOWN
9160 if (lchown == NULL) {
9161 if (PyObject_DelAttrString(m, "lchown") == -1) {
9162 return;
9163 }
9164 }
9165#endif /* HAVE_LCHOWN */
9166
9167
9168#endif /* __APPLE__ */
9169
Guido van Rossumb6775db1994-08-01 11:34:53 +00009170}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009171
9172#ifdef __cplusplus
9173}
9174#endif
9175
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009176