blob: c6481ac8b5e17c4632098b1109f3de579a25b67f [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
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000526#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000527static PyObject *
528posix_error_with_unicode_filename(Py_UNICODE* name)
529{
530 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
531}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000532#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000533
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
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000559static PyObject *
560win32_error_unicode(char* function, Py_UNICODE* filename)
561{
562 /* XXX - see win32_error for comments on 'function' */
563 errno = GetLastError();
564 if (filename)
565 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
566 else
567 return PyErr_SetFromWindowsErr(errno);
568}
569
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000570static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000571convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000572{
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000573 if (PyUnicode_CheckExact(*param))
574 Py_INCREF(*param);
575 else if (PyUnicode_Check(*param))
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000576 /* For a Unicode subtype that's not a Unicode object,
577 return a true Unicode object with the same data. */
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000578 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
579 PyUnicode_GET_SIZE(*param));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000580 else
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000581 *param = PyUnicode_FromEncodedObject(*param,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000582 Py_FileSystemDefaultEncoding,
583 "strict");
584 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000585}
586
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000587#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000588
Guido van Rossumd48f2521997-12-05 22:19:34 +0000589#if defined(PYOS_OS2)
590/**********************************************************************
591 * Helper Function to Trim and Format OS/2 Messages
592 **********************************************************************/
593 static void
594os2_formatmsg(char *msgbuf, int msglen, char *reason)
595{
596 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
597
598 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
599 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
600
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000601 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000602 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
603 }
604
605 /* Add Optional Reason Text */
606 if (reason) {
607 strcat(msgbuf, " : ");
608 strcat(msgbuf, reason);
609 }
610}
611
612/**********************************************************************
613 * Decode an OS/2 Operating System Error Code
614 *
615 * A convenience function to lookup an OS/2 error code and return a
616 * text message we can use to raise a Python exception.
617 *
618 * Notes:
619 * The messages for errors returned from the OS/2 kernel reside in
620 * the file OSO001.MSG in the \OS2 directory hierarchy.
621 *
622 **********************************************************************/
623 static char *
624os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
625{
626 APIRET rc;
627 ULONG msglen;
628
629 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
630 Py_BEGIN_ALLOW_THREADS
631 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
632 errorcode, "oso001.msg", &msglen);
633 Py_END_ALLOW_THREADS
634
635 if (rc == NO_ERROR)
636 os2_formatmsg(msgbuf, msglen, reason);
637 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000638 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000639 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000640
641 return msgbuf;
642}
643
644/* Set an OS/2-specific error and return NULL. OS/2 kernel
645 errors are not in a global variable e.g. 'errno' nor are
646 they congruent with posix error numbers. */
647
648static PyObject * os2_error(int code)
649{
650 char text[1024];
651 PyObject *v;
652
653 os2_strerror(text, sizeof(text), code, "");
654
655 v = Py_BuildValue("(is)", code, text);
656 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000657 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000658 Py_DECREF(v);
659 }
660 return NULL; /* Signal to Python that an Exception is Pending */
661}
662
663#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664
665/* POSIX generic methods */
666
Barry Warsaw53699e91996-12-10 23:23:01 +0000667static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000668posix_fildes(PyObject *fdobj, int (*func)(int))
669{
670 int fd;
671 int res;
672 fd = PyObject_AsFileDescriptor(fdobj);
673 if (fd < 0)
674 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000675 if (!_PyVerify_fd(fd))
676 return posix_error();
Fred Drake4d1e64b2002-04-15 19:40:07 +0000677 Py_BEGIN_ALLOW_THREADS
678 res = (*func)(fd);
679 Py_END_ALLOW_THREADS
680 if (res < 0)
681 return posix_error();
682 Py_INCREF(Py_None);
683 return Py_None;
684}
Guido van Rossum21142a01999-01-08 21:05:37 +0000685
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000686#ifdef MS_WINDOWS
Tim Peters11b23062003-04-23 02:39:17 +0000687static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000688unicode_file_names(void)
689{
690 static int canusewide = -1;
691 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000692 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000693 the Windows NT family. */
694 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
695 }
696 return canusewide;
697}
698#endif
Tim Peters11b23062003-04-23 02:39:17 +0000699
Guido van Rossum21142a01999-01-08 21:05:37 +0000700static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000701posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000702{
Mark Hammondef8b6542001-05-13 08:04:26 +0000703 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000704 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000705 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000706 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000707 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000708 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000709 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000710 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000711 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000712 return posix_error_with_allocated_filename(path1);
713 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000714 Py_INCREF(Py_None);
715 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000716}
717
Barry Warsaw53699e91996-12-10 23:23:01 +0000718static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000719posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000720 char *format,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000721 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000722{
Mark Hammondef8b6542001-05-13 08:04:26 +0000723 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000724 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000725 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000726 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000727 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000728 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000729 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000730 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000731 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000732 PyMem_Free(path1);
733 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000734 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000735 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000736 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000737 Py_INCREF(Py_None);
738 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000739}
740
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000741#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000742static PyObject*
743win32_1str(PyObject* args, char* func,
744 char* format, BOOL (__stdcall *funcA)(LPCSTR),
745 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
746{
747 PyObject *uni;
748 char *ansi;
749 BOOL result;
750 if (unicode_file_names()) {
751 if (!PyArg_ParseTuple(args, wformat, &uni))
752 PyErr_Clear();
753 else {
754 Py_BEGIN_ALLOW_THREADS
755 result = funcW(PyUnicode_AsUnicode(uni));
756 Py_END_ALLOW_THREADS
757 if (!result)
758 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
759 Py_INCREF(Py_None);
760 return Py_None;
761 }
762 }
763 if (!PyArg_ParseTuple(args, format, &ansi))
764 return NULL;
765 Py_BEGIN_ALLOW_THREADS
766 result = funcA(ansi);
767 Py_END_ALLOW_THREADS
768 if (!result)
769 return win32_error(func, ansi);
770 Py_INCREF(Py_None);
771 return Py_None;
772
773}
774
775/* This is a reimplementation of the C library's chdir function,
776 but one that produces Win32 errors instead of DOS error codes.
777 chdir is essentially a wrapper around SetCurrentDirectory; however,
778 it also needs to set "magic" environment variables indicating
779 the per-drive current directory, which are of the form =<drive>: */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000780static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000781win32_chdir(LPCSTR path)
782{
783 char new_path[MAX_PATH+1];
784 int result;
785 char env[4] = "=x:";
786
787 if(!SetCurrentDirectoryA(path))
788 return FALSE;
789 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
790 if (!result)
791 return FALSE;
792 /* In the ANSI API, there should not be any paths longer
793 than MAX_PATH. */
794 assert(result <= MAX_PATH+1);
795 if (strncmp(new_path, "\\\\", 2) == 0 ||
796 strncmp(new_path, "//", 2) == 0)
797 /* UNC path, nothing to do. */
798 return TRUE;
799 env[1] = new_path[0];
800 return SetEnvironmentVariableA(env, new_path);
801}
802
803/* The Unicode version differs from the ANSI version
804 since the current directory might exceed MAX_PATH characters */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000805static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000806win32_wchdir(LPCWSTR path)
807{
808 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
809 int result;
810 wchar_t env[4] = L"=x:";
811
812 if(!SetCurrentDirectoryW(path))
813 return FALSE;
814 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
815 if (!result)
816 return FALSE;
817 if (result > MAX_PATH+1) {
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000818 new_path = malloc(result * sizeof(wchar_t));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000819 if (!new_path) {
820 SetLastError(ERROR_OUTOFMEMORY);
821 return FALSE;
822 }
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000823 result = GetCurrentDirectoryW(result, new_path);
Hirokazu Yamamoto6c75a302008-10-09 10:11:21 +0000824 if (!result) {
825 free(new_path);
Hirokazu Yamamoto10a018c2008-10-09 10:00:30 +0000826 return FALSE;
Hirokazu Yamamoto6c75a302008-10-09 10:11:21 +0000827 }
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000828 }
829 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
830 wcsncmp(new_path, L"//", 2) == 0)
831 /* UNC path, nothing to do. */
832 return TRUE;
833 env[1] = new_path[0];
834 result = SetEnvironmentVariableW(env, new_path);
835 if (new_path != _new_path)
836 free(new_path);
837 return result;
838}
839#endif
840
Martin v. Löwis14694662006-02-03 12:54:16 +0000841#ifdef MS_WINDOWS
842/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
843 - time stamps are restricted to second resolution
844 - file modification times suffer from forth-and-back conversions between
845 UTC and local time
846 Therefore, we implement our own stat, based on the Win32 API directly.
847*/
848#define HAVE_STAT_NSEC 1
849
850struct win32_stat{
851 int st_dev;
852 __int64 st_ino;
853 unsigned short st_mode;
854 int st_nlink;
855 int st_uid;
856 int st_gid;
857 int st_rdev;
858 __int64 st_size;
859 int st_atime;
860 int st_atime_nsec;
861 int st_mtime;
862 int st_mtime_nsec;
863 int st_ctime;
864 int st_ctime_nsec;
865};
866
867static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
868
869static void
870FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
871{
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000872 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
873 /* Cannot simply cast and dereference in_ptr,
874 since it might not be aligned properly */
875 __int64 in;
876 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000877 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
878 /* XXX Win32 supports time stamps past 2038; we currently don't */
879 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
880}
881
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000882static void
883time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
884{
885 /* XXX endianness */
886 __int64 out;
887 out = time_in + secs_between_epochs;
Martin v. Löwisf43893a2006-10-09 20:44:25 +0000888 out = out * 10000000 + nsec_in / 100;
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000889 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000890}
891
Martin v. Löwis14694662006-02-03 12:54:16 +0000892/* Below, we *know* that ugo+r is 0444 */
893#if _S_IREAD != 0400
894#error Unsupported C library
895#endif
896static int
897attributes_to_mode(DWORD attr)
898{
899 int m = 0;
900 if (attr & FILE_ATTRIBUTE_DIRECTORY)
901 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
902 else
903 m |= _S_IFREG;
904 if (attr & FILE_ATTRIBUTE_READONLY)
905 m |= 0444;
906 else
907 m |= 0666;
908 return m;
909}
910
911static int
912attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
913{
914 memset(result, 0, sizeof(*result));
915 result->st_mode = attributes_to_mode(info->dwFileAttributes);
916 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
917 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
918 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
919 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
920
921 return 0;
922}
923
Martin v. Löwis012bc722006-10-15 09:43:39 +0000924/* Emulate GetFileAttributesEx[AW] on Windows 95 */
925static int checked = 0;
926static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
927static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
928static void
929check_gfax()
930{
931 HINSTANCE hKernel32;
932 if (checked)
933 return;
934 checked = 1;
935 hKernel32 = GetModuleHandle("KERNEL32");
936 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
937 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
938}
939
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000940static BOOL
941attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
942{
943 HANDLE hFindFile;
944 WIN32_FIND_DATAA FileData;
945 hFindFile = FindFirstFileA(pszFile, &FileData);
946 if (hFindFile == INVALID_HANDLE_VALUE)
947 return FALSE;
948 FindClose(hFindFile);
949 pfad->dwFileAttributes = FileData.dwFileAttributes;
950 pfad->ftCreationTime = FileData.ftCreationTime;
951 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
952 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
953 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
954 pfad->nFileSizeLow = FileData.nFileSizeLow;
955 return TRUE;
956}
957
958static BOOL
959attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
960{
961 HANDLE hFindFile;
962 WIN32_FIND_DATAW FileData;
963 hFindFile = FindFirstFileW(pszFile, &FileData);
964 if (hFindFile == INVALID_HANDLE_VALUE)
965 return FALSE;
966 FindClose(hFindFile);
967 pfad->dwFileAttributes = FileData.dwFileAttributes;
968 pfad->ftCreationTime = FileData.ftCreationTime;
969 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
970 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
971 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
972 pfad->nFileSizeLow = FileData.nFileSizeLow;
973 return TRUE;
974}
975
Martin v. Löwis012bc722006-10-15 09:43:39 +0000976static BOOL WINAPI
977Py_GetFileAttributesExA(LPCSTR pszFile,
978 GET_FILEEX_INFO_LEVELS level,
979 LPVOID pv)
980{
981 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000982 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
983 /* First try to use the system's implementation, if that is
984 available and either succeeds to gives an error other than
985 that it isn't implemented. */
986 check_gfax();
987 if (gfaxa) {
988 result = gfaxa(pszFile, level, pv);
989 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
990 return result;
991 }
992 /* It's either not present, or not implemented.
993 Emulate using FindFirstFile. */
994 if (level != GetFileExInfoStandard) {
995 SetLastError(ERROR_INVALID_PARAMETER);
996 return FALSE;
997 }
998 /* Use GetFileAttributes to validate that the file name
999 does not contain wildcards (which FindFirstFile would
1000 accept). */
1001 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
1002 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001003 return attributes_from_dir(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +00001004}
1005
1006static BOOL WINAPI
1007Py_GetFileAttributesExW(LPCWSTR pszFile,
1008 GET_FILEEX_INFO_LEVELS level,
1009 LPVOID pv)
1010{
1011 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +00001012 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1013 /* First try to use the system's implementation, if that is
1014 available and either succeeds to gives an error other than
1015 that it isn't implemented. */
1016 check_gfax();
1017 if (gfaxa) {
1018 result = gfaxw(pszFile, level, pv);
1019 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1020 return result;
1021 }
1022 /* It's either not present, or not implemented.
1023 Emulate using FindFirstFile. */
1024 if (level != GetFileExInfoStandard) {
1025 SetLastError(ERROR_INVALID_PARAMETER);
1026 return FALSE;
1027 }
1028 /* Use GetFileAttributes to validate that the file name
1029 does not contain wildcards (which FindFirstFile would
1030 accept). */
1031 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1032 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001033 return attributes_from_dir_w(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +00001034}
1035
Martin v. Löwis14694662006-02-03 12:54:16 +00001036static int
1037win32_stat(const char* path, struct win32_stat *result)
1038{
1039 WIN32_FILE_ATTRIBUTE_DATA info;
1040 int code;
1041 char *dot;
1042 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +00001043 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001044 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1045 /* Protocol violation: we explicitly clear errno, instead of
1046 setting it to a POSIX error. Callers should use GetLastError. */
1047 errno = 0;
1048 return -1;
1049 } else {
1050 /* Could not get attributes on open file. Fall back to
1051 reading the directory. */
1052 if (!attributes_from_dir(path, &info)) {
1053 /* Very strange. This should not fail now */
1054 errno = 0;
1055 return -1;
1056 }
1057 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001058 }
1059 code = attribute_data_to_stat(&info, result);
1060 if (code != 0)
1061 return code;
1062 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1063 dot = strrchr(path, '.');
1064 if (dot) {
1065 if (stricmp(dot, ".bat") == 0 ||
1066 stricmp(dot, ".cmd") == 0 ||
1067 stricmp(dot, ".exe") == 0 ||
1068 stricmp(dot, ".com") == 0)
1069 result->st_mode |= 0111;
1070 }
1071 return code;
1072}
1073
1074static int
1075win32_wstat(const wchar_t* path, struct win32_stat *result)
1076{
1077 int code;
1078 const wchar_t *dot;
1079 WIN32_FILE_ATTRIBUTE_DATA info;
1080 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +00001081 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001082 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1083 /* Protocol violation: we explicitly clear errno, instead of
1084 setting it to a POSIX error. Callers should use GetLastError. */
1085 errno = 0;
1086 return -1;
1087 } else {
1088 /* Could not get attributes on open file. Fall back to
1089 reading the directory. */
1090 if (!attributes_from_dir_w(path, &info)) {
1091 /* Very strange. This should not fail now */
1092 errno = 0;
1093 return -1;
1094 }
1095 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001096 }
1097 code = attribute_data_to_stat(&info, result);
1098 if (code < 0)
1099 return code;
1100 /* Set IFEXEC if it is an .exe, .bat, ... */
1101 dot = wcsrchr(path, '.');
1102 if (dot) {
1103 if (_wcsicmp(dot, L".bat") == 0 ||
1104 _wcsicmp(dot, L".cmd") == 0 ||
1105 _wcsicmp(dot, L".exe") == 0 ||
1106 _wcsicmp(dot, L".com") == 0)
1107 result->st_mode |= 0111;
1108 }
1109 return code;
1110}
1111
1112static int
1113win32_fstat(int file_number, struct win32_stat *result)
1114{
1115 BY_HANDLE_FILE_INFORMATION info;
1116 HANDLE h;
1117 int type;
1118
1119 h = (HANDLE)_get_osfhandle(file_number);
1120
1121 /* Protocol violation: we explicitly clear errno, instead of
1122 setting it to a POSIX error. Callers should use GetLastError. */
1123 errno = 0;
1124
1125 if (h == INVALID_HANDLE_VALUE) {
1126 /* This is really a C library error (invalid file handle).
1127 We set the Win32 error to the closes one matching. */
1128 SetLastError(ERROR_INVALID_HANDLE);
1129 return -1;
1130 }
1131 memset(result, 0, sizeof(*result));
1132
1133 type = GetFileType(h);
1134 if (type == FILE_TYPE_UNKNOWN) {
1135 DWORD error = GetLastError();
1136 if (error != 0) {
1137 return -1;
1138 }
1139 /* else: valid but unknown file */
1140 }
1141
1142 if (type != FILE_TYPE_DISK) {
1143 if (type == FILE_TYPE_CHAR)
1144 result->st_mode = _S_IFCHR;
1145 else if (type == FILE_TYPE_PIPE)
1146 result->st_mode = _S_IFIFO;
1147 return 0;
1148 }
1149
1150 if (!GetFileInformationByHandle(h, &info)) {
1151 return -1;
1152 }
1153
1154 /* similar to stat() */
1155 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1156 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1157 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1158 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1159 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1160 /* specific to fstat() */
1161 result->st_nlink = info.nNumberOfLinks;
1162 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1163 return 0;
1164}
1165
1166#endif /* MS_WINDOWS */
1167
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001168PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001169"stat_result: Result from stat or lstat.\n\n\
1170This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001171 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001172or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1173\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001174Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1175or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001176\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001177See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001178
1179static PyStructSequence_Field stat_result_fields[] = {
1180 {"st_mode", "protection bits"},
1181 {"st_ino", "inode"},
1182 {"st_dev", "device"},
1183 {"st_nlink", "number of hard links"},
1184 {"st_uid", "user ID of owner"},
1185 {"st_gid", "group ID of owner"},
1186 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001187 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1188 {NULL, "integer time of last access"},
1189 {NULL, "integer time of last modification"},
1190 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001191 {"st_atime", "time of last access"},
1192 {"st_mtime", "time of last modification"},
1193 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001194#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001195 {"st_blksize", "blocksize for filesystem I/O"},
1196#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001197#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001198 {"st_blocks", "number of blocks allocated"},
1199#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001200#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001201 {"st_rdev", "device type (if inode device)"},
1202#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001203#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1204 {"st_flags", "user defined flags for file"},
1205#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001206#ifdef HAVE_STRUCT_STAT_ST_GEN
1207 {"st_gen", "generation number"},
1208#endif
1209#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1210 {"st_birthtime", "time of creation"},
1211#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001212 {0}
1213};
1214
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001215#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001216#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001217#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001218#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001219#endif
1220
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001221#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001222#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1223#else
1224#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1225#endif
1226
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001227#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001228#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1229#else
1230#define ST_RDEV_IDX ST_BLOCKS_IDX
1231#endif
1232
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001233#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1234#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1235#else
1236#define ST_FLAGS_IDX ST_RDEV_IDX
1237#endif
1238
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001239#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001240#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001241#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001242#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001243#endif
1244
1245#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1246#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1247#else
1248#define ST_BIRTHTIME_IDX ST_GEN_IDX
1249#endif
1250
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001251static PyStructSequence_Desc stat_result_desc = {
1252 "stat_result", /* name */
1253 stat_result__doc__, /* doc */
1254 stat_result_fields,
1255 10
1256};
1257
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001258PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001259"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1260This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001261 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001262or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001263\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001264See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001265
1266static PyStructSequence_Field statvfs_result_fields[] = {
1267 {"f_bsize", },
1268 {"f_frsize", },
1269 {"f_blocks", },
1270 {"f_bfree", },
1271 {"f_bavail", },
1272 {"f_files", },
1273 {"f_ffree", },
1274 {"f_favail", },
1275 {"f_flag", },
1276 {"f_namemax",},
1277 {0}
1278};
1279
1280static PyStructSequence_Desc statvfs_result_desc = {
1281 "statvfs_result", /* name */
1282 statvfs_result__doc__, /* doc */
1283 statvfs_result_fields,
1284 10
1285};
1286
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001287static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001288static PyTypeObject StatResultType;
1289static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001290static newfunc structseq_new;
1291
1292static PyObject *
1293statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1294{
1295 PyStructSequence *result;
1296 int i;
1297
1298 result = (PyStructSequence*)structseq_new(type, args, kwds);
1299 if (!result)
1300 return NULL;
1301 /* If we have been initialized from a tuple,
1302 st_?time might be set to None. Initialize it
1303 from the int slots. */
1304 for (i = 7; i <= 9; i++) {
1305 if (result->ob_item[i+3] == Py_None) {
1306 Py_DECREF(Py_None);
1307 Py_INCREF(result->ob_item[i]);
1308 result->ob_item[i+3] = result->ob_item[i];
1309 }
1310 }
1311 return (PyObject*)result;
1312}
1313
1314
1315
1316/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001317static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001318
1319PyDoc_STRVAR(stat_float_times__doc__,
1320"stat_float_times([newval]) -> oldval\n\n\
1321Determine whether os.[lf]stat represents time stamps as float objects.\n\
1322If newval is True, future calls to stat() return floats, if it is False,\n\
1323future calls return ints. \n\
1324If newval is omitted, return the current setting.\n");
1325
1326static PyObject*
1327stat_float_times(PyObject* self, PyObject *args)
1328{
1329 int newval = -1;
1330 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1331 return NULL;
1332 if (newval == -1)
1333 /* Return old value */
1334 return PyBool_FromLong(_stat_float_times);
1335 _stat_float_times = newval;
1336 Py_INCREF(Py_None);
1337 return Py_None;
1338}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001339
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001340static void
1341fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1342{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001343 PyObject *fval,*ival;
1344#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001345 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001346#else
1347 ival = PyInt_FromLong((long)sec);
1348#endif
Neal Norwitze0a81af2006-08-12 01:50:38 +00001349 if (!ival)
1350 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001351 if (_stat_float_times) {
1352 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1353 } else {
1354 fval = ival;
1355 Py_INCREF(fval);
1356 }
1357 PyStructSequence_SET_ITEM(v, index, ival);
1358 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001359}
1360
Tim Peters5aa91602002-01-30 05:46:57 +00001361/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001362 (used by posix_stat() and posix_fstat()) */
1363static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001364_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001365{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001366 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001367 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001368 if (v == NULL)
1369 return NULL;
1370
Martin v. Löwis14694662006-02-03 12:54:16 +00001371 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001372#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001373 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001374 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001375#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001376 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001377#endif
1378#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001379 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001380 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001381#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001382 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001383#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001384 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1385 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1386 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001387#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001388 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001389 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001390#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001391 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001392#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001393
Martin v. Löwis14694662006-02-03 12:54:16 +00001394#if defined(HAVE_STAT_TV_NSEC)
1395 ansec = st->st_atim.tv_nsec;
1396 mnsec = st->st_mtim.tv_nsec;
1397 cnsec = st->st_ctim.tv_nsec;
1398#elif defined(HAVE_STAT_TV_NSEC2)
1399 ansec = st->st_atimespec.tv_nsec;
1400 mnsec = st->st_mtimespec.tv_nsec;
1401 cnsec = st->st_ctimespec.tv_nsec;
1402#elif defined(HAVE_STAT_NSEC)
1403 ansec = st->st_atime_nsec;
1404 mnsec = st->st_mtime_nsec;
1405 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001406#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001407 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001408#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001409 fill_time(v, 7, st->st_atime, ansec);
1410 fill_time(v, 8, st->st_mtime, mnsec);
1411 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001412
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001413#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001414 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001415 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001416#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001417#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001418 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001419 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001420#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001421#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001422 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001423 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001424#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001425#ifdef HAVE_STRUCT_STAT_ST_GEN
1426 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001427 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001428#endif
1429#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1430 {
1431 PyObject *val;
1432 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001433 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001434#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001435 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001436#else
1437 bnsec = 0;
1438#endif
1439 if (_stat_float_times) {
1440 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1441 } else {
1442 val = PyInt_FromLong((long)bsec);
1443 }
1444 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1445 val);
1446 }
1447#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001448#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1449 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001450 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001451#endif
Fred Drake699f3522000-06-29 21:12:41 +00001452
1453 if (PyErr_Occurred()) {
1454 Py_DECREF(v);
1455 return NULL;
1456 }
1457
1458 return v;
1459}
1460
Martin v. Löwisd8948722004-06-02 09:57:56 +00001461#ifdef MS_WINDOWS
1462
1463/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1464 where / can be used in place of \ and the trailing slash is optional.
1465 Both SERVER and SHARE must have at least one character.
1466*/
1467
1468#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1469#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001470#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001471#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001472#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001473
Tim Peters4ad82172004-08-30 17:02:04 +00001474static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001475IsUNCRootA(char *path, int pathlen)
1476{
1477 #define ISSLASH ISSLASHA
1478
1479 int i, share;
1480
1481 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1482 /* minimum UNCRoot is \\x\y */
1483 return FALSE;
1484 for (i = 2; i < pathlen ; i++)
1485 if (ISSLASH(path[i])) break;
1486 if (i == 2 || i == pathlen)
1487 /* do not allow \\\SHARE or \\SERVER */
1488 return FALSE;
1489 share = i+1;
1490 for (i = share; i < pathlen; i++)
1491 if (ISSLASH(path[i])) break;
1492 return (i != share && (i == pathlen || i == pathlen-1));
1493
1494 #undef ISSLASH
1495}
1496
Tim Peters4ad82172004-08-30 17:02:04 +00001497static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001498IsUNCRootW(Py_UNICODE *path, int pathlen)
1499{
1500 #define ISSLASH ISSLASHW
1501
1502 int i, share;
1503
1504 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1505 /* minimum UNCRoot is \\x\y */
1506 return FALSE;
1507 for (i = 2; i < pathlen ; i++)
1508 if (ISSLASH(path[i])) break;
1509 if (i == 2 || i == pathlen)
1510 /* do not allow \\\SHARE or \\SERVER */
1511 return FALSE;
1512 share = i+1;
1513 for (i = share; i < pathlen; i++)
1514 if (ISSLASH(path[i])) break;
1515 return (i != share && (i == pathlen || i == pathlen-1));
1516
1517 #undef ISSLASH
1518}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001519#endif /* MS_WINDOWS */
1520
Barry Warsaw53699e91996-12-10 23:23:01 +00001521static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001522posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001523 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001524#ifdef __VMS
1525 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1526#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001527 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001528#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001529 char *wformat,
1530 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001531{
Fred Drake699f3522000-06-29 21:12:41 +00001532 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001533 char *path = NULL; /* pass this to stat; do not free() it */
1534 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001535 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001536 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001537
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001538#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001539 /* If on wide-character-capable OS see if argument
1540 is Unicode and if so use wide API. */
1541 if (unicode_file_names()) {
1542 PyUnicodeObject *po;
1543 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001544 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1545
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001546 Py_BEGIN_ALLOW_THREADS
1547 /* PyUnicode_AS_UNICODE result OK without
1548 thread lock as it is a simple dereference. */
1549 res = wstatfunc(wpath, &st);
1550 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001551
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001552 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001553 return win32_error_unicode("stat", wpath);
1554 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001555 }
1556 /* Drop the argument parsing error as narrow strings
1557 are also valid. */
1558 PyErr_Clear();
1559 }
1560#endif
1561
Tim Peters5aa91602002-01-30 05:46:57 +00001562 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001563 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001564 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001565 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001566
Barry Warsaw53699e91996-12-10 23:23:01 +00001567 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001568 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001569 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001570
1571 if (res != 0) {
1572#ifdef MS_WINDOWS
1573 result = win32_error("stat", pathfree);
1574#else
1575 result = posix_error_with_filename(pathfree);
1576#endif
1577 }
1578 else
1579 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001580
Tim Peters500bd032001-12-19 19:05:01 +00001581 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001582 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001583}
1584
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001585/* POSIX methods */
1586
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001587PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001588"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001589Use the real uid/gid to test for access to a path. Note that most\n\
1590operations will use the effective uid/gid, therefore this routine can\n\
1591be used in a suid/sgid environment to test if the invoking user has the\n\
1592specified access to the path. The mode argument can be F_OK to test\n\
1593existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001594
1595static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001596posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001597{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001598 char *path;
1599 int mode;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001600
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001601#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001602 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001603 if (unicode_file_names()) {
1604 PyUnicodeObject *po;
1605 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1606 Py_BEGIN_ALLOW_THREADS
1607 /* PyUnicode_AS_UNICODE OK without thread lock as
1608 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001609 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001610 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001611 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001612 }
1613 /* Drop the argument parsing error as narrow strings
1614 are also valid. */
1615 PyErr_Clear();
1616 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001617 if (!PyArg_ParseTuple(args, "eti:access",
1618 Py_FileSystemDefaultEncoding, &path, &mode))
1619 return 0;
1620 Py_BEGIN_ALLOW_THREADS
1621 attr = GetFileAttributesA(path);
1622 Py_END_ALLOW_THREADS
1623 PyMem_Free(path);
1624finish:
1625 if (attr == 0xFFFFFFFF)
1626 /* File does not exist, or cannot read attributes */
1627 return PyBool_FromLong(0);
1628 /* Access is possible if either write access wasn't requested, or
Martin v. Löwis7b3cc062007-12-03 23:09:04 +00001629 the file isn't read-only, or if it's a directory, as there are
1630 no read-only directories on Windows. */
1631 return PyBool_FromLong(!(mode & 2)
1632 || !(attr & FILE_ATTRIBUTE_READONLY)
1633 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001634#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001635 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001636 if (!PyArg_ParseTuple(args, "eti:access",
1637 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001638 return NULL;
1639 Py_BEGIN_ALLOW_THREADS
1640 res = access(path, mode);
1641 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001642 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001643 return PyBool_FromLong(res == 0);
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001644#endif /* MS_WINDOWS */
Guido van Rossum94f6f721999-01-06 18:42:14 +00001645}
1646
Guido van Rossumd371ff11999-01-25 16:12:23 +00001647#ifndef F_OK
1648#define F_OK 0
1649#endif
1650#ifndef R_OK
1651#define R_OK 4
1652#endif
1653#ifndef W_OK
1654#define W_OK 2
1655#endif
1656#ifndef X_OK
1657#define X_OK 1
1658#endif
1659
1660#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001661PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001662"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001663Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001664
1665static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001666posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001667{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001668 int id;
1669 char *ret;
1670
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001671 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001672 return NULL;
1673
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001674#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001675 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001676 if (id == 0) {
1677 ret = ttyname();
1678 }
1679 else {
1680 ret = NULL;
1681 }
1682#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001683 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001684#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001685 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001686 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001687 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001688}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001689#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001690
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001691#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001692PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001693"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001694Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001695
1696static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001697posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001698{
1699 char *ret;
1700 char buffer[L_ctermid];
1701
Greg Wardb48bc172000-03-01 21:51:56 +00001702#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001703 ret = ctermid_r(buffer);
1704#else
1705 ret = ctermid(buffer);
1706#endif
1707 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001708 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001709 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001710}
1711#endif
1712
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001713PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001714"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001715Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001716
Barry Warsaw53699e91996-12-10 23:23:01 +00001717static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001718posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001719{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001720#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001721 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001722#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001723 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001724#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001725 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001726#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001727 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001728#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001729}
1730
Fred Drake4d1e64b2002-04-15 19:40:07 +00001731#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001732PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001733"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001734Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001735opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001736
1737static PyObject *
1738posix_fchdir(PyObject *self, PyObject *fdobj)
1739{
1740 return posix_fildes(fdobj, fchdir);
1741}
1742#endif /* HAVE_FCHDIR */
1743
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001744
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001745PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001746"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001747Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001748
Barry Warsaw53699e91996-12-10 23:23:01 +00001749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001750posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001751{
Mark Hammondef8b6542001-05-13 08:04:26 +00001752 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001753 int i;
1754 int res;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001755#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001756 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001757 if (unicode_file_names()) {
1758 PyUnicodeObject *po;
1759 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1760 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001761 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1762 if (attr != 0xFFFFFFFF) {
1763 if (i & _S_IWRITE)
1764 attr &= ~FILE_ATTRIBUTE_READONLY;
1765 else
1766 attr |= FILE_ATTRIBUTE_READONLY;
1767 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1768 }
1769 else
1770 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001771 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001772 if (!res)
1773 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001774 PyUnicode_AS_UNICODE(po));
1775 Py_INCREF(Py_None);
1776 return Py_None;
1777 }
1778 /* Drop the argument parsing error as narrow strings
1779 are also valid. */
1780 PyErr_Clear();
1781 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001782 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1783 &path, &i))
1784 return NULL;
1785 Py_BEGIN_ALLOW_THREADS
1786 attr = GetFileAttributesA(path);
1787 if (attr != 0xFFFFFFFF) {
1788 if (i & _S_IWRITE)
1789 attr &= ~FILE_ATTRIBUTE_READONLY;
1790 else
1791 attr |= FILE_ATTRIBUTE_READONLY;
1792 res = SetFileAttributesA(path, attr);
1793 }
1794 else
1795 res = 0;
1796 Py_END_ALLOW_THREADS
1797 if (!res) {
1798 win32_error("chmod", path);
1799 PyMem_Free(path);
1800 return NULL;
1801 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001802 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001803 Py_INCREF(Py_None);
1804 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001805#else /* MS_WINDOWS */
Mark Hammond817c9292003-12-03 01:22:38 +00001806 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001807 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001808 return NULL;
1809 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001810 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001811 Py_END_ALLOW_THREADS
1812 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001813 return posix_error_with_allocated_filename(path);
1814 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001815 Py_INCREF(Py_None);
1816 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001817#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001818}
1819
Christian Heimes36281872007-11-30 21:11:28 +00001820#ifdef HAVE_FCHMOD
1821PyDoc_STRVAR(posix_fchmod__doc__,
1822"fchmod(fd, mode)\n\n\
1823Change the access permissions of the file given by file\n\
1824descriptor fd.");
1825
1826static PyObject *
1827posix_fchmod(PyObject *self, PyObject *args)
1828{
1829 int fd, mode, res;
1830 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1831 return NULL;
1832 Py_BEGIN_ALLOW_THREADS
1833 res = fchmod(fd, mode);
1834 Py_END_ALLOW_THREADS
1835 if (res < 0)
1836 return posix_error();
1837 Py_RETURN_NONE;
1838}
1839#endif /* HAVE_FCHMOD */
1840
1841#ifdef HAVE_LCHMOD
1842PyDoc_STRVAR(posix_lchmod__doc__,
1843"lchmod(path, mode)\n\n\
1844Change the access permissions of a file. If path is a symlink, this\n\
1845affects the link itself rather than the target.");
1846
1847static PyObject *
1848posix_lchmod(PyObject *self, PyObject *args)
1849{
1850 char *path = NULL;
1851 int i;
1852 int res;
1853 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1854 &path, &i))
1855 return NULL;
1856 Py_BEGIN_ALLOW_THREADS
1857 res = lchmod(path, i);
1858 Py_END_ALLOW_THREADS
1859 if (res < 0)
1860 return posix_error_with_allocated_filename(path);
1861 PyMem_Free(path);
1862 Py_RETURN_NONE;
1863}
1864#endif /* HAVE_LCHMOD */
1865
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001866
Martin v. Löwis382abef2007-02-19 10:55:19 +00001867#ifdef HAVE_CHFLAGS
1868PyDoc_STRVAR(posix_chflags__doc__,
1869"chflags(path, flags)\n\n\
1870Set file flags.");
1871
1872static PyObject *
1873posix_chflags(PyObject *self, PyObject *args)
1874{
1875 char *path;
1876 unsigned long flags;
1877 int res;
1878 if (!PyArg_ParseTuple(args, "etk:chflags",
1879 Py_FileSystemDefaultEncoding, &path, &flags))
1880 return NULL;
1881 Py_BEGIN_ALLOW_THREADS
1882 res = chflags(path, flags);
1883 Py_END_ALLOW_THREADS
1884 if (res < 0)
1885 return posix_error_with_allocated_filename(path);
1886 PyMem_Free(path);
1887 Py_INCREF(Py_None);
1888 return Py_None;
1889}
1890#endif /* HAVE_CHFLAGS */
1891
1892#ifdef HAVE_LCHFLAGS
1893PyDoc_STRVAR(posix_lchflags__doc__,
1894"lchflags(path, flags)\n\n\
1895Set file flags.\n\
1896This function will not follow symbolic links.");
1897
1898static PyObject *
1899posix_lchflags(PyObject *self, PyObject *args)
1900{
1901 char *path;
1902 unsigned long flags;
1903 int res;
1904 if (!PyArg_ParseTuple(args, "etk:lchflags",
1905 Py_FileSystemDefaultEncoding, &path, &flags))
1906 return NULL;
1907 Py_BEGIN_ALLOW_THREADS
1908 res = lchflags(path, flags);
1909 Py_END_ALLOW_THREADS
1910 if (res < 0)
1911 return posix_error_with_allocated_filename(path);
1912 PyMem_Free(path);
1913 Py_INCREF(Py_None);
1914 return Py_None;
1915}
1916#endif /* HAVE_LCHFLAGS */
1917
Martin v. Löwis244edc82001-10-04 22:44:26 +00001918#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001919PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001920"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001921Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001922
1923static PyObject *
1924posix_chroot(PyObject *self, PyObject *args)
1925{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001926 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001927}
1928#endif
1929
Guido van Rossum21142a01999-01-08 21:05:37 +00001930#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001931PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001932"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001933force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001934
1935static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001936posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001937{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001938 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001939}
1940#endif /* HAVE_FSYNC */
1941
1942#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001943
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001944#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001945extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1946#endif
1947
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001948PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001949"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001950force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001951 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001952
1953static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001954posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001955{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001956 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001957}
1958#endif /* HAVE_FDATASYNC */
1959
1960
Fredrik Lundh10723342000-07-10 16:38:09 +00001961#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001962PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001963"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001964Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001965
Barry Warsaw53699e91996-12-10 23:23:01 +00001966static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001967posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001968{
Mark Hammondef8b6542001-05-13 08:04:26 +00001969 char *path = NULL;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001970 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001971 int res;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001972 if (!PyArg_ParseTuple(args, "etll:chown",
Tim Peters5aa91602002-01-30 05:46:57 +00001973 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001974 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001975 return NULL;
1976 Py_BEGIN_ALLOW_THREADS
1977 res = chown(path, (uid_t) uid, (gid_t) gid);
1978 Py_END_ALLOW_THREADS
1979 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001980 return posix_error_with_allocated_filename(path);
1981 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001982 Py_INCREF(Py_None);
1983 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001984}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001985#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001986
Christian Heimes36281872007-11-30 21:11:28 +00001987#ifdef HAVE_FCHOWN
1988PyDoc_STRVAR(posix_fchown__doc__,
1989"fchown(fd, uid, gid)\n\n\
1990Change the owner and group id of the file given by file descriptor\n\
1991fd to the numeric uid and gid.");
1992
1993static PyObject *
1994posix_fchown(PyObject *self, PyObject *args)
1995{
1996 int fd, uid, gid;
1997 int res;
1998 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
1999 return NULL;
2000 Py_BEGIN_ALLOW_THREADS
2001 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2002 Py_END_ALLOW_THREADS
2003 if (res < 0)
2004 return posix_error();
2005 Py_RETURN_NONE;
2006}
2007#endif /* HAVE_FCHOWN */
2008
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002009#ifdef HAVE_LCHOWN
2010PyDoc_STRVAR(posix_lchown__doc__,
2011"lchown(path, uid, gid)\n\n\
2012Change the owner and group id of path to the numeric uid and gid.\n\
2013This function will not follow symbolic links.");
2014
2015static PyObject *
2016posix_lchown(PyObject *self, PyObject *args)
2017{
2018 char *path = NULL;
2019 int uid, gid;
2020 int res;
2021 if (!PyArg_ParseTuple(args, "etii:lchown",
2022 Py_FileSystemDefaultEncoding, &path,
2023 &uid, &gid))
2024 return NULL;
2025 Py_BEGIN_ALLOW_THREADS
2026 res = lchown(path, (uid_t) uid, (gid_t) gid);
2027 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00002028 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002029 return posix_error_with_allocated_filename(path);
2030 PyMem_Free(path);
2031 Py_INCREF(Py_None);
2032 return Py_None;
2033}
2034#endif /* HAVE_LCHOWN */
2035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002036
Guido van Rossum36bc6801995-06-14 22:54:23 +00002037#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002038PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002039"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002040Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002041
Barry Warsaw53699e91996-12-10 23:23:01 +00002042static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002043posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002044{
Facundo Batista5596b0c2008-06-22 13:36:20 +00002045 int bufsize_incr = 1024;
2046 int bufsize = 0;
2047 char *tmpbuf = NULL;
2048 char *res = NULL;
2049 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00002050
Barry Warsaw53699e91996-12-10 23:23:01 +00002051 Py_BEGIN_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002052 do {
2053 bufsize = bufsize + bufsize_incr;
2054 tmpbuf = malloc(bufsize);
2055 if (tmpbuf == NULL) {
2056 break;
2057 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002058#if defined(PYOS_OS2) && defined(PYCC_GCC)
Facundo Batista5596b0c2008-06-22 13:36:20 +00002059 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002060#else
Facundo Batista5596b0c2008-06-22 13:36:20 +00002061 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002062#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00002063
2064 if (res == NULL) {
2065 free(tmpbuf);
2066 }
2067 } while ((res == NULL) && (errno == ERANGE));
Barry Warsaw53699e91996-12-10 23:23:01 +00002068 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002069
Guido van Rossumff4949e1992-08-05 19:58:53 +00002070 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002071 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002072
2073 dynamic_return = PyString_FromString(tmpbuf);
2074 free(tmpbuf);
2075
2076 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002077}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002078
Walter Dörwald3b918c32002-11-21 20:18:46 +00002079#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002080PyDoc_STRVAR(posix_getcwdu__doc__,
2081"getcwdu() -> path\n\n\
2082Return a unicode string representing the current working directory.");
2083
2084static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002085posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002086{
2087 char buf[1026];
2088 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002089
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002090#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002091 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002092 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002093 wchar_t wbuf[1026];
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002094 wchar_t *wbuf2 = wbuf;
2095 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002096 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002097 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2098 /* If the buffer is large enough, len does not include the
2099 terminating \0. If the buffer is too small, len includes
2100 the space needed for the terminator. */
2101 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2102 wbuf2 = malloc(len * sizeof(wchar_t));
2103 if (wbuf2)
2104 len = GetCurrentDirectoryW(len, wbuf2);
2105 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002106 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002107 if (!wbuf2) {
2108 PyErr_NoMemory();
2109 return NULL;
2110 }
2111 if (!len) {
2112 if (wbuf2 != wbuf) free(wbuf2);
2113 return win32_error("getcwdu", NULL);
2114 }
2115 resobj = PyUnicode_FromWideChar(wbuf2, len);
2116 if (wbuf2 != wbuf) free(wbuf2);
2117 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002118 }
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002119#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002120
2121 Py_BEGIN_ALLOW_THREADS
2122#if defined(PYOS_OS2) && defined(PYCC_GCC)
2123 res = _getcwd2(buf, sizeof buf);
2124#else
2125 res = getcwd(buf, sizeof buf);
2126#endif
2127 Py_END_ALLOW_THREADS
2128 if (res == NULL)
2129 return posix_error();
2130 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2131}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002132#endif /* Py_USING_UNICODE */
2133#endif /* HAVE_GETCWD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002134
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002135
Guido van Rossumb6775db1994-08-01 11:34:53 +00002136#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002137PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002138"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002139Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002140
Barry Warsaw53699e91996-12-10 23:23:01 +00002141static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002142posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002143{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002144 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002145}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002146#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002147
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002148
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002149PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002150"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002151Return a list containing the names of the entries in the directory.\n\
2152\n\
2153 path: path of directory to list\n\
2154\n\
2155The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002156entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002157
Barry Warsaw53699e91996-12-10 23:23:01 +00002158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002159posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002160{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002161 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002162 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002163#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002164
Barry Warsaw53699e91996-12-10 23:23:01 +00002165 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002166 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002167 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002168 WIN32_FIND_DATA FileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002169 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002170 char *bufptr = namebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002171 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002172
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002173 /* If on wide-character-capable OS see if argument
2174 is Unicode and if so use wide API. */
2175 if (unicode_file_names()) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002176 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002177 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2178 WIN32_FIND_DATAW wFileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002179 Py_UNICODE *wnamebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002180 /* Overallocate for \\*.*\0 */
2181 len = PyUnicode_GET_SIZE(po);
2182 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2183 if (!wnamebuf) {
2184 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002185 return NULL;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002186 }
2187 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
Hirokazu Yamamoto406d7aa2009-05-04 05:28:39 +00002188 if (len > 0) {
2189 Py_UNICODE wch = wnamebuf[len-1];
2190 if (wch != L'/' && wch != L'\\' && wch != L':')
2191 wnamebuf[len++] = L'\\';
2192 wcscpy(wnamebuf + len, L"*.*");
2193 }
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002194 if ((d = PyList_New(0)) == NULL) {
2195 free(wnamebuf);
2196 return NULL;
2197 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002198 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2199 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002200 int error = GetLastError();
2201 if (error == ERROR_FILE_NOT_FOUND) {
2202 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002203 return d;
2204 }
2205 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002206 win32_error_unicode("FindFirstFileW", wnamebuf);
2207 free(wnamebuf);
2208 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002209 }
2210 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002211 /* Skip over . and .. */
2212 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2213 wcscmp(wFileData.cFileName, L"..") != 0) {
2214 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2215 if (v == NULL) {
2216 Py_DECREF(d);
2217 d = NULL;
2218 break;
2219 }
2220 if (PyList_Append(d, v) != 0) {
2221 Py_DECREF(v);
2222 Py_DECREF(d);
2223 d = NULL;
2224 break;
2225 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002226 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002227 }
Georg Brandl622927b2006-03-07 12:48:03 +00002228 Py_BEGIN_ALLOW_THREADS
2229 result = FindNextFileW(hFindFile, &wFileData);
2230 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002231 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2232 it got to the end of the directory. */
2233 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2234 Py_DECREF(d);
2235 win32_error_unicode("FindNextFileW", wnamebuf);
2236 FindClose(hFindFile);
2237 free(wnamebuf);
2238 return NULL;
2239 }
Georg Brandl622927b2006-03-07 12:48:03 +00002240 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002241
2242 if (FindClose(hFindFile) == FALSE) {
2243 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002244 win32_error_unicode("FindClose", wnamebuf);
2245 free(wnamebuf);
2246 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002247 }
Martin v. Löwise3edaea2006-05-15 05:51:36 +00002248 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002249 return d;
2250 }
2251 /* Drop the argument parsing error as narrow strings
2252 are also valid. */
2253 PyErr_Clear();
2254 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002255
Tim Peters5aa91602002-01-30 05:46:57 +00002256 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002257 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002258 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002259 if (len > 0) {
2260 char ch = namebuf[len-1];
2261 if (ch != SEP && ch != ALTSEP && ch != ':')
2262 namebuf[len++] = '/';
Hirokazu Yamamoto406d7aa2009-05-04 05:28:39 +00002263 strcpy(namebuf + len, "*.*");
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002264 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002265
Barry Warsaw53699e91996-12-10 23:23:01 +00002266 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002267 return NULL;
2268
2269 hFindFile = FindFirstFile(namebuf, &FileData);
2270 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002271 int error = GetLastError();
2272 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002273 return d;
2274 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002275 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002276 }
2277 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002278 /* Skip over . and .. */
2279 if (strcmp(FileData.cFileName, ".") != 0 &&
2280 strcmp(FileData.cFileName, "..") != 0) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002281 v = PyString_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002282 if (v == NULL) {
2283 Py_DECREF(d);
2284 d = NULL;
2285 break;
2286 }
2287 if (PyList_Append(d, v) != 0) {
2288 Py_DECREF(v);
2289 Py_DECREF(d);
2290 d = NULL;
2291 break;
2292 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002293 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002294 }
Georg Brandl622927b2006-03-07 12:48:03 +00002295 Py_BEGIN_ALLOW_THREADS
2296 result = FindNextFile(hFindFile, &FileData);
2297 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002298 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2299 it got to the end of the directory. */
2300 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2301 Py_DECREF(d);
2302 win32_error("FindNextFile", namebuf);
2303 FindClose(hFindFile);
2304 return NULL;
2305 }
Georg Brandl622927b2006-03-07 12:48:03 +00002306 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002307
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002308 if (FindClose(hFindFile) == FALSE) {
2309 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002310 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002311 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002312
2313 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002314
Tim Peters0bb44a42000-09-15 07:44:49 +00002315#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002316
2317#ifndef MAX_PATH
2318#define MAX_PATH CCHMAXPATH
2319#endif
2320 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002321 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002322 PyObject *d, *v;
2323 char namebuf[MAX_PATH+5];
2324 HDIR hdir = 1;
2325 ULONG srchcnt = 1;
2326 FILEFINDBUF3 ep;
2327 APIRET rc;
2328
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002329 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002330 return NULL;
2331 if (len >= MAX_PATH) {
2332 PyErr_SetString(PyExc_ValueError, "path too long");
2333 return NULL;
2334 }
2335 strcpy(namebuf, name);
2336 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002337 if (*pt == ALTSEP)
2338 *pt = SEP;
2339 if (namebuf[len-1] != SEP)
2340 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002341 strcpy(namebuf + len, "*.*");
2342
2343 if ((d = PyList_New(0)) == NULL)
2344 return NULL;
2345
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002346 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2347 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002348 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002349 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2350 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2351 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002352
2353 if (rc != NO_ERROR) {
2354 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002355 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002356 }
2357
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002358 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002359 do {
2360 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002361 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002362 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002363
2364 strcpy(namebuf, ep.achName);
2365
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002366 /* Leave Case of Name Alone -- In Native Form */
2367 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002368
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002369 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002370 if (v == NULL) {
2371 Py_DECREF(d);
2372 d = NULL;
2373 break;
2374 }
2375 if (PyList_Append(d, v) != 0) {
2376 Py_DECREF(v);
2377 Py_DECREF(d);
2378 d = NULL;
2379 break;
2380 }
2381 Py_DECREF(v);
2382 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2383 }
2384
2385 return d;
2386#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002387
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002388 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002389 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002390 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002391 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002392 int arg_is_unicode = 1;
2393
Georg Brandl05e89b82006-04-11 07:04:06 +00002394 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002395 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2396 arg_is_unicode = 0;
2397 PyErr_Clear();
2398 }
2399 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002400 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002401 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002402 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002403 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002404 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002405 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002406 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002407 return NULL;
2408 }
Georg Brandl622927b2006-03-07 12:48:03 +00002409 for (;;) {
Georg Brandl86cbf812008-07-16 21:31:41 +00002410 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002411 Py_BEGIN_ALLOW_THREADS
2412 ep = readdir(dirp);
2413 Py_END_ALLOW_THREADS
Georg Brandl86cbf812008-07-16 21:31:41 +00002414 if (ep == NULL) {
2415 if (errno == 0) {
2416 break;
2417 } else {
2418 closedir(dirp);
2419 Py_DECREF(d);
2420 return posix_error_with_allocated_filename(name);
2421 }
2422 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002423 if (ep->d_name[0] == '.' &&
2424 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002425 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002426 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002427 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002428 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002429 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002430 d = NULL;
2431 break;
2432 }
Just van Rossum46c97842003-02-25 21:42:15 +00002433#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002434 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002435 PyObject *w;
2436
2437 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002438 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002439 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002440 if (w != NULL) {
2441 Py_DECREF(v);
2442 v = w;
2443 }
2444 else {
2445 /* fall back to the original byte string, as
2446 discussed in patch #683592 */
2447 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002448 }
Just van Rossum46c97842003-02-25 21:42:15 +00002449 }
2450#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002451 if (PyList_Append(d, v) != 0) {
2452 Py_DECREF(v);
2453 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002454 d = NULL;
2455 break;
2456 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002457 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002458 }
2459 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002460 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002461
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002462 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002463
Tim Peters0bb44a42000-09-15 07:44:49 +00002464#endif /* which OS */
2465} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002466
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002467#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002468/* A helper function for abspath on win32 */
2469static PyObject *
2470posix__getfullpathname(PyObject *self, PyObject *args)
2471{
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00002472 /* assume encoded strings won't more than double no of chars */
Mark Hammondef8b6542001-05-13 08:04:26 +00002473 char inbuf[MAX_PATH*2];
2474 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002475 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002476 char outbuf[MAX_PATH*2];
2477 char *temp;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002478
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002479 if (unicode_file_names()) {
2480 PyUnicodeObject *po;
2481 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
Hirokazu Yamamotoed29bb42008-11-08 03:46:17 +00002482 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2483 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002484 Py_UNICODE *wtemp;
Hirokazu Yamamotoed29bb42008-11-08 03:46:17 +00002485 DWORD result;
2486 PyObject *v;
2487 result = GetFullPathNameW(wpath,
2488 sizeof(woutbuf)/sizeof(woutbuf[0]),
2489 woutbuf, &wtemp);
2490 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2491 woutbufp = malloc(result * sizeof(Py_UNICODE));
2492 if (!woutbufp)
2493 return PyErr_NoMemory();
2494 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2495 }
2496 if (result)
2497 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2498 else
2499 v = win32_error_unicode("GetFullPathNameW", wpath);
2500 if (woutbufp != woutbuf)
2501 free(woutbufp);
2502 return v;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002503 }
2504 /* Drop the argument parsing error as narrow strings
2505 are also valid. */
2506 PyErr_Clear();
2507 }
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002508
Tim Peters5aa91602002-01-30 05:46:57 +00002509 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2510 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002511 &insize))
2512 return NULL;
2513 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2514 outbuf, &temp))
2515 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002516 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2517 return PyUnicode_Decode(outbuf, strlen(outbuf),
2518 Py_FileSystemDefaultEncoding, NULL);
2519 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002520 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002521} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002522#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002523
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002524PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002525"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002526Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002527
Barry Warsaw53699e91996-12-10 23:23:01 +00002528static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002529posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002530{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002531 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002532 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002533 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002534
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002535#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002536 if (unicode_file_names()) {
2537 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002538 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002539 Py_BEGIN_ALLOW_THREADS
2540 /* PyUnicode_AS_UNICODE OK without thread lock as
2541 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002542 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002543 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002544 if (!res)
2545 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002546 Py_INCREF(Py_None);
2547 return Py_None;
2548 }
2549 /* Drop the argument parsing error as narrow strings
2550 are also valid. */
2551 PyErr_Clear();
2552 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002553 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2554 Py_FileSystemDefaultEncoding, &path, &mode))
2555 return NULL;
2556 Py_BEGIN_ALLOW_THREADS
2557 /* PyUnicode_AS_UNICODE OK without thread lock as
2558 it is a simple dereference. */
2559 res = CreateDirectoryA(path, NULL);
2560 Py_END_ALLOW_THREADS
2561 if (!res) {
2562 win32_error("mkdir", path);
2563 PyMem_Free(path);
2564 return NULL;
2565 }
2566 PyMem_Free(path);
2567 Py_INCREF(Py_None);
2568 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002569#else /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002570
Tim Peters5aa91602002-01-30 05:46:57 +00002571 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002572 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002573 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002574 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002575#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002576 res = mkdir(path);
2577#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002578 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002579#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002580 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002581 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002582 return posix_error_with_allocated_filename(path);
2583 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002584 Py_INCREF(Py_None);
2585 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002586#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002587}
2588
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002589
Neal Norwitz1818ed72006-03-26 00:29:48 +00002590/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2591#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002592#include <sys/resource.h>
2593#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002594
Neal Norwitz1818ed72006-03-26 00:29:48 +00002595
2596#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002597PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002598"nice(inc) -> new_priority\n\n\
2599Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002600
Barry Warsaw53699e91996-12-10 23:23:01 +00002601static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002602posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002603{
2604 int increment, value;
2605
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002606 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002607 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002608
2609 /* There are two flavours of 'nice': one that returns the new
2610 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002611 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2612 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002613
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002614 If we are of the nice family that returns the new priority, we
2615 need to clear errno before the call, and check if errno is filled
2616 before calling posix_error() on a returnvalue of -1, because the
2617 -1 may be the actual new priority! */
2618
2619 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002620 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002621#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002622 if (value == 0)
2623 value = getpriority(PRIO_PROCESS, 0);
2624#endif
2625 if (value == -1 && errno != 0)
2626 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002627 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002628 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002629}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002630#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002631
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002632PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002633"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002634Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002635
Barry Warsaw53699e91996-12-10 23:23:01 +00002636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002637posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002638{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002639#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002640 PyObject *o1, *o2;
2641 char *p1, *p2;
2642 BOOL result;
2643 if (unicode_file_names()) {
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002644 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2645 goto error;
2646 if (!convert_to_unicode(&o1))
2647 goto error;
2648 if (!convert_to_unicode(&o2)) {
2649 Py_DECREF(o1);
2650 goto error;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002651 }
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002652 Py_BEGIN_ALLOW_THREADS
2653 result = MoveFileW(PyUnicode_AsUnicode(o1),
2654 PyUnicode_AsUnicode(o2));
2655 Py_END_ALLOW_THREADS
2656 Py_DECREF(o1);
2657 Py_DECREF(o2);
2658 if (!result)
2659 return win32_error("rename", NULL);
2660 Py_INCREF(Py_None);
2661 return Py_None;
2662error:
2663 PyErr_Clear();
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002664 }
2665 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2666 return NULL;
2667 Py_BEGIN_ALLOW_THREADS
2668 result = MoveFileA(p1, p2);
2669 Py_END_ALLOW_THREADS
2670 if (!result)
2671 return win32_error("rename", NULL);
2672 Py_INCREF(Py_None);
2673 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002674#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002675 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002676#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002677}
2678
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002679
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002680PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002681"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002682Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002683
Barry Warsaw53699e91996-12-10 23:23:01 +00002684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002685posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002686{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002687#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002688 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002689#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002690 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002691#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002692}
2693
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002694
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002695PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002696"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002697Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002698
Barry Warsaw53699e91996-12-10 23:23:01 +00002699static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002700posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002701{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002702#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002703 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002704#else
2705 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2706#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002707}
2708
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002709
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002710#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002711PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002712"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002713Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002714
Barry Warsaw53699e91996-12-10 23:23:01 +00002715static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002716posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002717{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002718 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002719 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002720 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002721 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002722 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002723 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002724 Py_END_ALLOW_THREADS
2725 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002726}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002727#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002728
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002729
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002730PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002731"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002732Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002733
Barry Warsaw53699e91996-12-10 23:23:01 +00002734static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002735posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002736{
2737 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002738 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002739 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002740 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002741 if (i < 0)
2742 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002743 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002744}
2745
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002746
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002747PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002748"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002749Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002750
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002751PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002752"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002753Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002754
Barry Warsaw53699e91996-12-10 23:23:01 +00002755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002756posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002757{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002758#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002759 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002760#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002761 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002762#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002763}
2764
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002765
Guido van Rossumb6775db1994-08-01 11:34:53 +00002766#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002767PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002768"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002769Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002770
Barry Warsaw53699e91996-12-10 23:23:01 +00002771static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002772posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002773{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002774 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002775 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002776
Barry Warsaw53699e91996-12-10 23:23:01 +00002777 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002778 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002779 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002780 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002781 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002782 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002783 u.sysname,
2784 u.nodename,
2785 u.release,
2786 u.version,
2787 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002788}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002789#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002790
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002791static int
2792extract_time(PyObject *t, long* sec, long* usec)
2793{
2794 long intval;
2795 if (PyFloat_Check(t)) {
2796 double tval = PyFloat_AsDouble(t);
Christian Heimese93237d2007-12-19 02:37:44 +00002797 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002798 if (!intobj)
2799 return -1;
2800 intval = PyInt_AsLong(intobj);
2801 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002802 if (intval == -1 && PyErr_Occurred())
2803 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002804 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002805 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002806 if (*usec < 0)
2807 /* If rounding gave us a negative number,
2808 truncate. */
2809 *usec = 0;
2810 return 0;
2811 }
2812 intval = PyInt_AsLong(t);
2813 if (intval == -1 && PyErr_Occurred())
2814 return -1;
2815 *sec = intval;
2816 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002817 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002818}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002819
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002820PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002821"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002822utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002823Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002824second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002825
Barry Warsaw53699e91996-12-10 23:23:01 +00002826static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002827posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002828{
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002829#ifdef MS_WINDOWS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002830 PyObject *arg;
2831 PyUnicodeObject *obwpath;
2832 wchar_t *wpath = NULL;
2833 char *apath = NULL;
2834 HANDLE hFile;
2835 long atimesec, mtimesec, ausec, musec;
2836 FILETIME atime, mtime;
2837 PyObject *result = NULL;
2838
2839 if (unicode_file_names()) {
2840 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2841 wpath = PyUnicode_AS_UNICODE(obwpath);
2842 Py_BEGIN_ALLOW_THREADS
2843 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002844 NULL, OPEN_EXISTING,
2845 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002846 Py_END_ALLOW_THREADS
2847 if (hFile == INVALID_HANDLE_VALUE)
2848 return win32_error_unicode("utime", wpath);
2849 } else
2850 /* Drop the argument parsing error as narrow strings
2851 are also valid. */
2852 PyErr_Clear();
2853 }
2854 if (!wpath) {
2855 if (!PyArg_ParseTuple(args, "etO:utime",
2856 Py_FileSystemDefaultEncoding, &apath, &arg))
2857 return NULL;
2858 Py_BEGIN_ALLOW_THREADS
2859 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002860 NULL, OPEN_EXISTING,
2861 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002862 Py_END_ALLOW_THREADS
2863 if (hFile == INVALID_HANDLE_VALUE) {
2864 win32_error("utime", apath);
2865 PyMem_Free(apath);
2866 return NULL;
2867 }
2868 PyMem_Free(apath);
2869 }
2870
2871 if (arg == Py_None) {
2872 SYSTEMTIME now;
2873 GetSystemTime(&now);
2874 if (!SystemTimeToFileTime(&now, &mtime) ||
2875 !SystemTimeToFileTime(&now, &atime)) {
2876 win32_error("utime", NULL);
2877 goto done;
2878 }
2879 }
2880 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2881 PyErr_SetString(PyExc_TypeError,
2882 "utime() arg 2 must be a tuple (atime, mtime)");
2883 goto done;
2884 }
2885 else {
2886 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2887 &atimesec, &ausec) == -1)
2888 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002889 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002890 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2891 &mtimesec, &musec) == -1)
2892 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002893 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002894 }
2895 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2896 /* Avoid putting the file name into the error here,
2897 as that may confuse the user into believing that
2898 something is wrong with the file, when it also
2899 could be the time stamp that gives a problem. */
2900 win32_error("utime", NULL);
2901 }
2902 Py_INCREF(Py_None);
2903 result = Py_None;
2904done:
2905 CloseHandle(hFile);
2906 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002907#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002908
Neal Norwitz2adf2102004-06-09 01:46:02 +00002909 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002910 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002911 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002912 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002913
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002914#if defined(HAVE_UTIMES)
2915 struct timeval buf[2];
2916#define ATIME buf[0].tv_sec
2917#define MTIME buf[1].tv_sec
2918#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002919/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002920 struct utimbuf buf;
2921#define ATIME buf.actime
2922#define MTIME buf.modtime
2923#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002924#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002925 time_t buf[2];
2926#define ATIME buf[0]
2927#define MTIME buf[1]
2928#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002929#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002930
Mark Hammond817c9292003-12-03 01:22:38 +00002931
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002932 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002933 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002934 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002935 if (arg == Py_None) {
2936 /* optional time values not given */
2937 Py_BEGIN_ALLOW_THREADS
2938 res = utime(path, NULL);
2939 Py_END_ALLOW_THREADS
2940 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002941 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002942 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002943 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002944 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002945 return NULL;
2946 }
2947 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002948 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002949 &atime, &ausec) == -1) {
2950 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002951 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002952 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002953 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002954 &mtime, &musec) == -1) {
2955 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002956 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002957 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002958 ATIME = atime;
2959 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002960#ifdef HAVE_UTIMES
2961 buf[0].tv_usec = ausec;
2962 buf[1].tv_usec = musec;
2963 Py_BEGIN_ALLOW_THREADS
2964 res = utimes(path, buf);
2965 Py_END_ALLOW_THREADS
2966#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002967 Py_BEGIN_ALLOW_THREADS
2968 res = utime(path, UTIME_ARG);
2969 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002970#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002971 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002972 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002973 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002974 }
Neal Norwitz96652712004-06-06 20:40:27 +00002975 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002976 Py_INCREF(Py_None);
2977 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002978#undef UTIME_ARG
2979#undef ATIME
2980#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002981#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002982}
2983
Guido van Rossum85e3b011991-06-03 12:42:10 +00002984
Guido van Rossum3b066191991-06-04 19:40:25 +00002985/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002986
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002987PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002988"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002989Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002990
Barry Warsaw53699e91996-12-10 23:23:01 +00002991static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002992posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002993{
2994 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002995 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002996 return NULL;
2997 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002998 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002999}
3000
Martin v. Löwis114619e2002-10-07 06:44:21 +00003001#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3002static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003003free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003004{
Martin v. Löwis725507b2006-03-07 12:08:51 +00003005 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00003006 for (i = 0; i < count; i++)
3007 PyMem_Free(array[i]);
3008 PyMem_DEL(array);
3009}
3010#endif
3011
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003012
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003013#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003014PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003015"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003016Execute an executable path with arguments, replacing current process.\n\
3017\n\
3018 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003019 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003020
Barry Warsaw53699e91996-12-10 23:23:01 +00003021static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003022posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003023{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003024 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003025 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003026 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003027 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003028 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003029
Guido van Rossum89b33251993-10-22 14:26:06 +00003030 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00003031 argv is a list or tuple of strings. */
3032
Martin v. Löwis114619e2002-10-07 06:44:21 +00003033 if (!PyArg_ParseTuple(args, "etO:execv",
3034 Py_FileSystemDefaultEncoding,
3035 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003036 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003037 if (PyList_Check(argv)) {
3038 argc = PyList_Size(argv);
3039 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003040 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003041 else if (PyTuple_Check(argv)) {
3042 argc = PyTuple_Size(argv);
3043 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003044 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003045 else {
Fred Drake661ea262000-10-24 19:57:45 +00003046 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003047 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00003048 return NULL;
3049 }
3050
Barry Warsaw53699e91996-12-10 23:23:01 +00003051 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003052 if (argvlist == NULL) {
3053 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003054 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003055 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003056 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003057 if (!PyArg_Parse((*getitem)(argv, i), "et",
3058 Py_FileSystemDefaultEncoding,
3059 &argvlist[i])) {
3060 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00003061 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00003062 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003063 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00003064 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003065
Guido van Rossum85e3b011991-06-03 12:42:10 +00003066 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003067 }
3068 argvlist[argc] = NULL;
3069
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003070 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003071
Guido van Rossum85e3b011991-06-03 12:42:10 +00003072 /* If we get here it's definitely an error */
3073
Martin v. Löwis114619e2002-10-07 06:44:21 +00003074 free_string_array(argvlist, argc);
3075 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003076 return posix_error();
3077}
3078
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003079
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003080PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003081"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003082Execute a path with arguments and environment, replacing current process.\n\
3083\n\
3084 path: path of executable file\n\
3085 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003086 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003087
Barry Warsaw53699e91996-12-10 23:23:01 +00003088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003089posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003090{
3091 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003092 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003093 char **argvlist;
3094 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003095 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003096 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003097 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003098 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003099
3100 /* execve has three arguments: (path, argv, env), where
3101 argv is a list or tuple of strings and env is a dictionary
3102 like posix.environ. */
3103
Martin v. Löwis114619e2002-10-07 06:44:21 +00003104 if (!PyArg_ParseTuple(args, "etOO:execve",
3105 Py_FileSystemDefaultEncoding,
3106 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003107 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003108 if (PyList_Check(argv)) {
3109 argc = PyList_Size(argv);
3110 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003111 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003112 else if (PyTuple_Check(argv)) {
3113 argc = PyTuple_Size(argv);
3114 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003115 }
3116 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003117 PyErr_SetString(PyExc_TypeError,
3118 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003119 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003120 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003121 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003122 PyErr_SetString(PyExc_TypeError,
3123 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003124 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003125 }
3126
Barry Warsaw53699e91996-12-10 23:23:01 +00003127 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003128 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003129 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003130 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003131 }
3132 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003133 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003134 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003135 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003136 &argvlist[i]))
3137 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003138 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003139 goto fail_1;
3140 }
3141 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003142 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003143 argvlist[argc] = NULL;
3144
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003145 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003146 if (i < 0)
3147 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003148 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003149 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003150 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003151 goto fail_1;
3152 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003153 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003154 keys = PyMapping_Keys(env);
3155 vals = PyMapping_Values(env);
3156 if (!keys || !vals)
3157 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003158 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3159 PyErr_SetString(PyExc_TypeError,
3160 "execve(): env.keys() or env.values() is not a list");
3161 goto fail_2;
3162 }
Tim Peters5aa91602002-01-30 05:46:57 +00003163
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003164 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003165 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003166 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003167
3168 key = PyList_GetItem(keys, pos);
3169 val = PyList_GetItem(vals, pos);
3170 if (!key || !val)
3171 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003172
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003173 if (!PyArg_Parse(
3174 key,
3175 "s;execve() arg 3 contains a non-string key",
3176 &k) ||
3177 !PyArg_Parse(
3178 val,
3179 "s;execve() arg 3 contains a non-string value",
3180 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003181 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003182 goto fail_2;
3183 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003184
3185#if defined(PYOS_OS2)
3186 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3187 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3188#endif
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003189 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003190 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003191 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003192 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003193 goto fail_2;
3194 }
Tim Petersc8996f52001-12-03 20:41:00 +00003195 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003196 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003197#if defined(PYOS_OS2)
3198 }
3199#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003200 }
3201 envlist[envc] = 0;
3202
3203 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003204
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003205 /* If we get here it's definitely an error */
3206
3207 (void) posix_error();
3208
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003209 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003210 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003211 PyMem_DEL(envlist[envc]);
3212 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003213 fail_1:
3214 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003215 Py_XDECREF(vals);
3216 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003217 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003218 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003219 return NULL;
3220}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003221#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003222
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003223
Guido van Rossuma1065681999-01-25 23:20:23 +00003224#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003225PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003226"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003227Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003228\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003229 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003230 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003231 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003232
3233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003234posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003235{
3236 char *path;
3237 PyObject *argv;
3238 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003239 int mode, i;
3240 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003241 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003242 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003243
3244 /* spawnv has three arguments: (mode, path, argv), where
3245 argv is a list or tuple of strings. */
3246
Martin v. Löwis114619e2002-10-07 06:44:21 +00003247 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3248 Py_FileSystemDefaultEncoding,
3249 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003250 return NULL;
3251 if (PyList_Check(argv)) {
3252 argc = PyList_Size(argv);
3253 getitem = PyList_GetItem;
3254 }
3255 else if (PyTuple_Check(argv)) {
3256 argc = PyTuple_Size(argv);
3257 getitem = PyTuple_GetItem;
3258 }
3259 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003260 PyErr_SetString(PyExc_TypeError,
3261 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003262 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003263 return NULL;
3264 }
3265
3266 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003267 if (argvlist == NULL) {
3268 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003269 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003270 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003271 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003272 if (!PyArg_Parse((*getitem)(argv, i), "et",
3273 Py_FileSystemDefaultEncoding,
3274 &argvlist[i])) {
3275 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003276 PyErr_SetString(
3277 PyExc_TypeError,
3278 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003279 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003280 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003281 }
3282 }
3283 argvlist[argc] = NULL;
3284
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003285#if defined(PYOS_OS2) && defined(PYCC_GCC)
3286 Py_BEGIN_ALLOW_THREADS
3287 spawnval = spawnv(mode, path, argvlist);
3288 Py_END_ALLOW_THREADS
3289#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003290 if (mode == _OLD_P_OVERLAY)
3291 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003292
Tim Peters25059d32001-12-07 20:35:43 +00003293 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003294 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003295 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003296#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003297
Martin v. Löwis114619e2002-10-07 06:44:21 +00003298 free_string_array(argvlist, argc);
3299 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003300
Fred Drake699f3522000-06-29 21:12:41 +00003301 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003302 return posix_error();
3303 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003304#if SIZEOF_LONG == SIZEOF_VOID_P
3305 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003306#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003307 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003308#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003309}
3310
3311
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003312PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003313"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003314Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003315\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003316 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003317 path: path of executable file\n\
3318 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003319 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003320
3321static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003322posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003323{
3324 char *path;
3325 PyObject *argv, *env;
3326 char **argvlist;
3327 char **envlist;
3328 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003329 int mode, pos, envc;
3330 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003331 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003332 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003333 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003334
3335 /* spawnve has four arguments: (mode, path, argv, env), where
3336 argv is a list or tuple of strings and env is a dictionary
3337 like posix.environ. */
3338
Martin v. Löwis114619e2002-10-07 06:44:21 +00003339 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3340 Py_FileSystemDefaultEncoding,
3341 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003342 return NULL;
3343 if (PyList_Check(argv)) {
3344 argc = PyList_Size(argv);
3345 getitem = PyList_GetItem;
3346 }
3347 else if (PyTuple_Check(argv)) {
3348 argc = PyTuple_Size(argv);
3349 getitem = PyTuple_GetItem;
3350 }
3351 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003352 PyErr_SetString(PyExc_TypeError,
3353 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003354 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003355 }
3356 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003357 PyErr_SetString(PyExc_TypeError,
3358 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003359 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003360 }
3361
3362 argvlist = PyMem_NEW(char *, argc+1);
3363 if (argvlist == NULL) {
3364 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003365 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003366 }
3367 for (i = 0; i < argc; i++) {
3368 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003369 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003370 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003371 &argvlist[i]))
3372 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003373 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003374 goto fail_1;
3375 }
3376 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003377 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003378 argvlist[argc] = NULL;
3379
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003380 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003381 if (i < 0)
3382 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003383 envlist = PyMem_NEW(char *, i + 1);
3384 if (envlist == NULL) {
3385 PyErr_NoMemory();
3386 goto fail_1;
3387 }
3388 envc = 0;
3389 keys = PyMapping_Keys(env);
3390 vals = PyMapping_Values(env);
3391 if (!keys || !vals)
3392 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003393 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3394 PyErr_SetString(PyExc_TypeError,
3395 "spawnve(): env.keys() or env.values() is not a list");
3396 goto fail_2;
3397 }
Tim Peters5aa91602002-01-30 05:46:57 +00003398
Guido van Rossuma1065681999-01-25 23:20:23 +00003399 for (pos = 0; pos < i; pos++) {
3400 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003401 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003402
3403 key = PyList_GetItem(keys, pos);
3404 val = PyList_GetItem(vals, pos);
3405 if (!key || !val)
3406 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003407
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003408 if (!PyArg_Parse(
3409 key,
3410 "s;spawnve() arg 3 contains a non-string key",
3411 &k) ||
3412 !PyArg_Parse(
3413 val,
3414 "s;spawnve() arg 3 contains a non-string value",
3415 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003416 {
3417 goto fail_2;
3418 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003419 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003420 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003421 if (p == NULL) {
3422 PyErr_NoMemory();
3423 goto fail_2;
3424 }
Tim Petersc8996f52001-12-03 20:41:00 +00003425 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003426 envlist[envc++] = p;
3427 }
3428 envlist[envc] = 0;
3429
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003430#if defined(PYOS_OS2) && defined(PYCC_GCC)
3431 Py_BEGIN_ALLOW_THREADS
3432 spawnval = spawnve(mode, path, argvlist, envlist);
3433 Py_END_ALLOW_THREADS
3434#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003435 if (mode == _OLD_P_OVERLAY)
3436 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003437
3438 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003439 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003440 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003441#endif
Tim Peters25059d32001-12-07 20:35:43 +00003442
Fred Drake699f3522000-06-29 21:12:41 +00003443 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003444 (void) posix_error();
3445 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003446#if SIZEOF_LONG == SIZEOF_VOID_P
3447 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003448#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003449 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003450#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003451
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003452 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003453 while (--envc >= 0)
3454 PyMem_DEL(envlist[envc]);
3455 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003456 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003457 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003458 Py_XDECREF(vals);
3459 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003460 fail_0:
3461 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003462 return res;
3463}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003464
3465/* OS/2 supports spawnvp & spawnvpe natively */
3466#if defined(PYOS_OS2)
3467PyDoc_STRVAR(posix_spawnvp__doc__,
3468"spawnvp(mode, file, args)\n\n\
3469Execute the program 'file' in a new process, using the environment\n\
3470search path to find the file.\n\
3471\n\
3472 mode: mode of process creation\n\
3473 file: executable file name\n\
3474 args: tuple or list of strings");
3475
3476static PyObject *
3477posix_spawnvp(PyObject *self, PyObject *args)
3478{
3479 char *path;
3480 PyObject *argv;
3481 char **argvlist;
3482 int mode, i, argc;
3483 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003484 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003485
3486 /* spawnvp has three arguments: (mode, path, argv), where
3487 argv is a list or tuple of strings. */
3488
3489 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3490 Py_FileSystemDefaultEncoding,
3491 &path, &argv))
3492 return NULL;
3493 if (PyList_Check(argv)) {
3494 argc = PyList_Size(argv);
3495 getitem = PyList_GetItem;
3496 }
3497 else if (PyTuple_Check(argv)) {
3498 argc = PyTuple_Size(argv);
3499 getitem = PyTuple_GetItem;
3500 }
3501 else {
3502 PyErr_SetString(PyExc_TypeError,
3503 "spawnvp() arg 2 must be a tuple or list");
3504 PyMem_Free(path);
3505 return NULL;
3506 }
3507
3508 argvlist = PyMem_NEW(char *, argc+1);
3509 if (argvlist == NULL) {
3510 PyMem_Free(path);
3511 return PyErr_NoMemory();
3512 }
3513 for (i = 0; i < argc; i++) {
3514 if (!PyArg_Parse((*getitem)(argv, i), "et",
3515 Py_FileSystemDefaultEncoding,
3516 &argvlist[i])) {
3517 free_string_array(argvlist, i);
3518 PyErr_SetString(
3519 PyExc_TypeError,
3520 "spawnvp() arg 2 must contain only strings");
3521 PyMem_Free(path);
3522 return NULL;
3523 }
3524 }
3525 argvlist[argc] = NULL;
3526
3527 Py_BEGIN_ALLOW_THREADS
3528#if defined(PYCC_GCC)
3529 spawnval = spawnvp(mode, path, argvlist);
3530#else
3531 spawnval = _spawnvp(mode, path, argvlist);
3532#endif
3533 Py_END_ALLOW_THREADS
3534
3535 free_string_array(argvlist, argc);
3536 PyMem_Free(path);
3537
3538 if (spawnval == -1)
3539 return posix_error();
3540 else
3541 return Py_BuildValue("l", (long) spawnval);
3542}
3543
3544
3545PyDoc_STRVAR(posix_spawnvpe__doc__,
3546"spawnvpe(mode, file, args, env)\n\n\
3547Execute the program 'file' in a new process, using the environment\n\
3548search path to find the file.\n\
3549\n\
3550 mode: mode of process creation\n\
3551 file: executable file name\n\
3552 args: tuple or list of arguments\n\
3553 env: dictionary of strings mapping to strings");
3554
3555static PyObject *
3556posix_spawnvpe(PyObject *self, PyObject *args)
3557{
3558 char *path;
3559 PyObject *argv, *env;
3560 char **argvlist;
3561 char **envlist;
3562 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3563 int mode, i, pos, argc, envc;
3564 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003565 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003566 int lastarg = 0;
3567
3568 /* spawnvpe has four arguments: (mode, path, argv, env), where
3569 argv is a list or tuple of strings and env is a dictionary
3570 like posix.environ. */
3571
3572 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3573 Py_FileSystemDefaultEncoding,
3574 &path, &argv, &env))
3575 return NULL;
3576 if (PyList_Check(argv)) {
3577 argc = PyList_Size(argv);
3578 getitem = PyList_GetItem;
3579 }
3580 else if (PyTuple_Check(argv)) {
3581 argc = PyTuple_Size(argv);
3582 getitem = PyTuple_GetItem;
3583 }
3584 else {
3585 PyErr_SetString(PyExc_TypeError,
3586 "spawnvpe() arg 2 must be a tuple or list");
3587 goto fail_0;
3588 }
3589 if (!PyMapping_Check(env)) {
3590 PyErr_SetString(PyExc_TypeError,
3591 "spawnvpe() arg 3 must be a mapping object");
3592 goto fail_0;
3593 }
3594
3595 argvlist = PyMem_NEW(char *, argc+1);
3596 if (argvlist == NULL) {
3597 PyErr_NoMemory();
3598 goto fail_0;
3599 }
3600 for (i = 0; i < argc; i++) {
3601 if (!PyArg_Parse((*getitem)(argv, i),
3602 "et;spawnvpe() arg 2 must contain only strings",
3603 Py_FileSystemDefaultEncoding,
3604 &argvlist[i]))
3605 {
3606 lastarg = i;
3607 goto fail_1;
3608 }
3609 }
3610 lastarg = argc;
3611 argvlist[argc] = NULL;
3612
3613 i = PyMapping_Size(env);
3614 if (i < 0)
3615 goto fail_1;
3616 envlist = PyMem_NEW(char *, i + 1);
3617 if (envlist == NULL) {
3618 PyErr_NoMemory();
3619 goto fail_1;
3620 }
3621 envc = 0;
3622 keys = PyMapping_Keys(env);
3623 vals = PyMapping_Values(env);
3624 if (!keys || !vals)
3625 goto fail_2;
3626 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3627 PyErr_SetString(PyExc_TypeError,
3628 "spawnvpe(): env.keys() or env.values() is not a list");
3629 goto fail_2;
3630 }
3631
3632 for (pos = 0; pos < i; pos++) {
3633 char *p, *k, *v;
3634 size_t len;
3635
3636 key = PyList_GetItem(keys, pos);
3637 val = PyList_GetItem(vals, pos);
3638 if (!key || !val)
3639 goto fail_2;
3640
3641 if (!PyArg_Parse(
3642 key,
3643 "s;spawnvpe() arg 3 contains a non-string key",
3644 &k) ||
3645 !PyArg_Parse(
3646 val,
3647 "s;spawnvpe() arg 3 contains a non-string value",
3648 &v))
3649 {
3650 goto fail_2;
3651 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003652 len = PyString_Size(key) + PyString_Size(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003653 p = PyMem_NEW(char, len);
3654 if (p == NULL) {
3655 PyErr_NoMemory();
3656 goto fail_2;
3657 }
3658 PyOS_snprintf(p, len, "%s=%s", k, v);
3659 envlist[envc++] = p;
3660 }
3661 envlist[envc] = 0;
3662
3663 Py_BEGIN_ALLOW_THREADS
3664#if defined(PYCC_GCC)
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003665 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003666#else
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003667 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003668#endif
3669 Py_END_ALLOW_THREADS
3670
3671 if (spawnval == -1)
3672 (void) posix_error();
3673 else
3674 res = Py_BuildValue("l", (long) spawnval);
3675
3676 fail_2:
3677 while (--envc >= 0)
3678 PyMem_DEL(envlist[envc]);
3679 PyMem_DEL(envlist);
3680 fail_1:
3681 free_string_array(argvlist, lastarg);
3682 Py_XDECREF(vals);
3683 Py_XDECREF(keys);
3684 fail_0:
3685 PyMem_Free(path);
3686 return res;
3687}
3688#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003689#endif /* HAVE_SPAWNV */
3690
3691
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003692#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003693PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003694"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003695Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3696\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003697Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003698
3699static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003700posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003701{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003702 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003703 if (pid == -1)
3704 return posix_error();
Gregory P. Smithfb7a50f2008-07-14 06:06:48 +00003705 if (pid == 0)
3706 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003707 return PyInt_FromLong(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003708}
3709#endif
3710
3711
Guido van Rossumad0ee831995-03-01 10:34:45 +00003712#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003713PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003714"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003715Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003716Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003717
Barry Warsaw53699e91996-12-10 23:23:01 +00003718static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003719posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003720{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003721 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003722 if (pid == -1)
3723 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003724 if (pid == 0)
3725 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003726 return PyInt_FromLong(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003727}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003728#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003729
Neal Norwitzb59798b2003-03-21 01:43:31 +00003730/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003731/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3732#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003733#define DEV_PTY_FILE "/dev/ptc"
3734#define HAVE_DEV_PTMX
3735#else
3736#define DEV_PTY_FILE "/dev/ptmx"
3737#endif
3738
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003739#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003740#ifdef HAVE_PTY_H
3741#include <pty.h>
3742#else
3743#ifdef HAVE_LIBUTIL_H
3744#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003745#endif /* HAVE_LIBUTIL_H */
3746#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003747#ifdef HAVE_STROPTS_H
3748#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003749#endif
3750#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003751
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003752#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003753PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003754"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003755Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003756
3757static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003758posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003759{
3760 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003761#ifndef HAVE_OPENPTY
3762 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003763#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003764#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003765 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003766#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003767 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003768#endif
3769#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003770
Thomas Wouters70c21a12000-07-14 14:28:33 +00003771#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003772 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3773 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003774#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003775 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3776 if (slave_name == NULL)
3777 return posix_error();
3778
3779 slave_fd = open(slave_name, O_RDWR);
3780 if (slave_fd < 0)
3781 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003782#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003783 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003784 if (master_fd < 0)
3785 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003786 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003787 /* change permission of slave */
3788 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003789 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003790 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003791 }
3792 /* unlock slave */
3793 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003794 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003795 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003796 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003797 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003798 slave_name = ptsname(master_fd); /* get name of slave */
3799 if (slave_name == NULL)
3800 return posix_error();
3801 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3802 if (slave_fd < 0)
3803 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003804#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003805 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3806 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003807#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003808 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003809#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003810#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003811#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003812
Fred Drake8cef4cf2000-06-28 16:40:38 +00003813 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003814
Fred Drake8cef4cf2000-06-28 16:40:38 +00003815}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003816#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003817
3818#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003819PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003820"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003821Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3822Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003823To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003824
3825static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003826posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003827{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003828 int master_fd = -1;
3829 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003830
Fred Drake8cef4cf2000-06-28 16:40:38 +00003831 pid = forkpty(&master_fd, NULL, NULL, NULL);
3832 if (pid == -1)
3833 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003834 if (pid == 0)
3835 PyOS_AfterFork();
Christian Heimes951cc0f2008-01-31 23:08:23 +00003836 return Py_BuildValue("(li)", pid, master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003837}
3838#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003839
Guido van Rossumad0ee831995-03-01 10:34:45 +00003840#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003841PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003842"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003843Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003844
Barry Warsaw53699e91996-12-10 23:23:01 +00003845static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003846posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003847{
Barry Warsaw53699e91996-12-10 23:23:01 +00003848 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003849}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003850#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003851
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003852
Guido van Rossumad0ee831995-03-01 10:34:45 +00003853#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003854PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003855"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003856Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003857
Barry Warsaw53699e91996-12-10 23:23:01 +00003858static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003859posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003860{
Barry Warsaw53699e91996-12-10 23:23:01 +00003861 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003862}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003863#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003864
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003865
Guido van Rossumad0ee831995-03-01 10:34:45 +00003866#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003867PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003868"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003869Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003870
Barry Warsaw53699e91996-12-10 23:23:01 +00003871static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003872posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003873{
Barry Warsaw53699e91996-12-10 23:23:01 +00003874 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003875}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003876#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003877
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003878
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003879PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003880"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003881Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003882
Barry Warsaw53699e91996-12-10 23:23:01 +00003883static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003884posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003885{
Barry Warsaw53699e91996-12-10 23:23:01 +00003886 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003887}
3888
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003889
Fred Drakec9680921999-12-13 16:37:25 +00003890#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003891PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003892"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003893Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003894
3895static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003896posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003897{
3898 PyObject *result = NULL;
3899
Fred Drakec9680921999-12-13 16:37:25 +00003900#ifdef NGROUPS_MAX
3901#define MAX_GROUPS NGROUPS_MAX
3902#else
3903 /* defined to be 16 on Solaris7, so this should be a small number */
3904#define MAX_GROUPS 64
3905#endif
3906 gid_t grouplist[MAX_GROUPS];
3907 int n;
3908
3909 n = getgroups(MAX_GROUPS, grouplist);
3910 if (n < 0)
3911 posix_error();
3912 else {
3913 result = PyList_New(n);
3914 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003915 int i;
3916 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003917 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003918 if (o == NULL) {
3919 Py_DECREF(result);
3920 result = NULL;
3921 break;
3922 }
3923 PyList_SET_ITEM(result, i, o);
3924 }
3925 }
3926 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003927
Fred Drakec9680921999-12-13 16:37:25 +00003928 return result;
3929}
3930#endif
3931
Martin v. Löwis606edc12002-06-13 21:09:11 +00003932#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003933PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003934"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003935Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003936
3937static PyObject *
3938posix_getpgid(PyObject *self, PyObject *args)
3939{
3940 int pid, pgid;
3941 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3942 return NULL;
3943 pgid = getpgid(pid);
3944 if (pgid < 0)
3945 return posix_error();
3946 return PyInt_FromLong((long)pgid);
3947}
3948#endif /* HAVE_GETPGID */
3949
3950
Guido van Rossumb6775db1994-08-01 11:34:53 +00003951#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003952PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003953"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003954Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003955
Barry Warsaw53699e91996-12-10 23:23:01 +00003956static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003957posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003958{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003959#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003960 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003961#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003962 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003963#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003964}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003965#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003966
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003967
Guido van Rossumb6775db1994-08-01 11:34:53 +00003968#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003969PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003970"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003971Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003972
Barry Warsaw53699e91996-12-10 23:23:01 +00003973static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003974posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003975{
Guido van Rossum64933891994-10-20 21:56:42 +00003976#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003977 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003978#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003979 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003980#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003981 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003982 Py_INCREF(Py_None);
3983 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003984}
3985
Guido van Rossumb6775db1994-08-01 11:34:53 +00003986#endif /* HAVE_SETPGRP */
3987
Guido van Rossumad0ee831995-03-01 10:34:45 +00003988#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003989PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003990"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003991Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003992
Barry Warsaw53699e91996-12-10 23:23:01 +00003993static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003994posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003995{
Christian Heimesd491d712008-02-01 18:49:26 +00003996 return PyInt_FromLong(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003997}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003998#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003999
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004000
Fred Drake12c6e2d1999-12-14 21:25:03 +00004001#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004002PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004003"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004004Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004005
4006static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004007posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004008{
Neal Norwitze241ce82003-02-17 18:17:05 +00004009 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00004010 char *name;
4011 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004012
Fred Drakea30680b2000-12-06 21:24:28 +00004013 errno = 0;
4014 name = getlogin();
4015 if (name == NULL) {
4016 if (errno)
4017 posix_error();
4018 else
4019 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00004020 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00004021 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00004022 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00004023 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00004024 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004025
Fred Drake12c6e2d1999-12-14 21:25:03 +00004026 return result;
4027}
4028#endif
4029
Guido van Rossumad0ee831995-03-01 10:34:45 +00004030#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004031PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004032"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004033Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004034
Barry Warsaw53699e91996-12-10 23:23:01 +00004035static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004036posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004037{
Barry Warsaw53699e91996-12-10 23:23:01 +00004038 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004039}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004040#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004041
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004042
Guido van Rossumad0ee831995-03-01 10:34:45 +00004043#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004044PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004045"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004046Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004047
Barry Warsaw53699e91996-12-10 23:23:01 +00004048static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004049posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004050{
Christian Heimesd491d712008-02-01 18:49:26 +00004051 pid_t pid;
4052 int sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004053 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00004054 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004055#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004056 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4057 APIRET rc;
4058 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004059 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004060
4061 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4062 APIRET rc;
4063 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004064 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004065
4066 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004067 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004068#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00004069 if (kill(pid, sig) == -1)
4070 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004071#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004072 Py_INCREF(Py_None);
4073 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004074}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004075#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004076
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004077#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004078PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004079"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004080Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004081
4082static PyObject *
4083posix_killpg(PyObject *self, PyObject *args)
4084{
4085 int pgid, sig;
4086 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
4087 return NULL;
4088 if (killpg(pgid, sig) == -1)
4089 return posix_error();
4090 Py_INCREF(Py_None);
4091 return Py_None;
4092}
4093#endif
4094
Guido van Rossumc0125471996-06-28 18:55:32 +00004095#ifdef HAVE_PLOCK
4096
4097#ifdef HAVE_SYS_LOCK_H
4098#include <sys/lock.h>
4099#endif
4100
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004101PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004102"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004103Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004104
Barry Warsaw53699e91996-12-10 23:23:01 +00004105static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004106posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004107{
4108 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004109 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004110 return NULL;
4111 if (plock(op) == -1)
4112 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004113 Py_INCREF(Py_None);
4114 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004115}
4116#endif
4117
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004118
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004119#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004120PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004121"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004122Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004123
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004124#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004125#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004126static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004127async_system(const char *command)
4128{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004129 char errormsg[256], args[1024];
4130 RESULTCODES rcodes;
4131 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004132
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004133 char *shell = getenv("COMSPEC");
4134 if (!shell)
4135 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004136
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004137 /* avoid overflowing the argument buffer */
4138 if (strlen(shell) + 3 + strlen(command) >= 1024)
4139 return ERROR_NOT_ENOUGH_MEMORY
4140
4141 args[0] = '\0';
4142 strcat(args, shell);
4143 strcat(args, "/c ");
4144 strcat(args, command);
4145
4146 /* execute asynchronously, inheriting the environment */
4147 rc = DosExecPgm(errormsg,
4148 sizeof(errormsg),
4149 EXEC_ASYNC,
4150 args,
4151 NULL,
4152 &rcodes,
4153 shell);
4154 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004155}
4156
Guido van Rossumd48f2521997-12-05 22:19:34 +00004157static FILE *
4158popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004159{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004160 int oldfd, tgtfd;
4161 HFILE pipeh[2];
4162 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004163
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004164 /* mode determines which of stdin or stdout is reconnected to
4165 * the pipe to the child
4166 */
4167 if (strchr(mode, 'r') != NULL) {
4168 tgt_fd = 1; /* stdout */
4169 } else if (strchr(mode, 'w')) {
4170 tgt_fd = 0; /* stdin */
4171 } else {
4172 *err = ERROR_INVALID_ACCESS;
4173 return NULL;
4174 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004175
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00004176 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004177 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4178 *err = rc;
4179 return NULL;
4180 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004181
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004182 /* prevent other threads accessing stdio */
4183 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004184
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004185 /* reconnect stdio and execute child */
4186 oldfd = dup(tgtfd);
4187 close(tgtfd);
4188 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4189 DosClose(pipeh[tgtfd]);
4190 rc = async_system(command);
4191 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004192
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004193 /* restore stdio */
4194 dup2(oldfd, tgtfd);
4195 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004196
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004197 /* allow other threads access to stdio */
4198 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004199
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004200 /* if execution of child was successful return file stream */
4201 if (rc == NO_ERROR)
4202 return fdopen(pipeh[1 - tgtfd], mode);
4203 else {
4204 DosClose(pipeh[1 - tgtfd]);
4205 *err = rc;
4206 return NULL;
4207 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004208}
4209
4210static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004211posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004212{
4213 char *name;
4214 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00004215 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004216 FILE *fp;
4217 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004218 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004219 return NULL;
4220 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00004221 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004222 Py_END_ALLOW_THREADS
4223 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004224 return os2_error(err);
4225
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004226 f = PyFile_FromFile(fp, name, mode, fclose);
4227 if (f != NULL)
4228 PyFile_SetBufSize(f, bufsize);
4229 return f;
4230}
4231
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004232#elif defined(PYCC_GCC)
4233
4234/* standard posix version of popen() support */
4235static PyObject *
4236posix_popen(PyObject *self, PyObject *args)
4237{
4238 char *name;
4239 char *mode = "r";
4240 int bufsize = -1;
4241 FILE *fp;
4242 PyObject *f;
4243 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4244 return NULL;
4245 Py_BEGIN_ALLOW_THREADS
4246 fp = popen(name, mode);
4247 Py_END_ALLOW_THREADS
4248 if (fp == NULL)
4249 return posix_error();
4250 f = PyFile_FromFile(fp, name, mode, pclose);
4251 if (f != NULL)
4252 PyFile_SetBufSize(f, bufsize);
4253 return f;
4254}
4255
4256/* fork() under OS/2 has lots'o'warts
4257 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4258 * most of this code is a ripoff of the win32 code, but using the
4259 * capabilities of EMX's C library routines
4260 */
4261
4262/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4263#define POPEN_1 1
4264#define POPEN_2 2
4265#define POPEN_3 3
4266#define POPEN_4 4
4267
4268static PyObject *_PyPopen(char *, int, int, int);
4269static int _PyPclose(FILE *file);
4270
4271/*
4272 * Internal dictionary mapping popen* file pointers to process handles,
4273 * for use when retrieving the process exit code. See _PyPclose() below
4274 * for more information on this dictionary's use.
4275 */
4276static PyObject *_PyPopenProcs = NULL;
4277
4278/* os2emx version of popen2()
4279 *
4280 * The result of this function is a pipe (file) connected to the
4281 * process's stdin, and a pipe connected to the process's stdout.
4282 */
4283
4284static PyObject *
4285os2emx_popen2(PyObject *self, PyObject *args)
4286{
4287 PyObject *f;
4288 int tm=0;
4289
4290 char *cmdstring;
4291 char *mode = "t";
4292 int bufsize = -1;
4293 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4294 return NULL;
4295
4296 if (*mode == 't')
4297 tm = O_TEXT;
4298 else if (*mode != 'b') {
4299 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4300 return NULL;
4301 } else
4302 tm = O_BINARY;
4303
4304 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4305
4306 return f;
4307}
4308
4309/*
4310 * Variation on os2emx.popen2
4311 *
4312 * The result of this function is 3 pipes - the process's stdin,
4313 * stdout and stderr
4314 */
4315
4316static PyObject *
4317os2emx_popen3(PyObject *self, PyObject *args)
4318{
4319 PyObject *f;
4320 int tm = 0;
4321
4322 char *cmdstring;
4323 char *mode = "t";
4324 int bufsize = -1;
4325 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4326 return NULL;
4327
4328 if (*mode == 't')
4329 tm = O_TEXT;
4330 else if (*mode != 'b') {
4331 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4332 return NULL;
4333 } else
4334 tm = O_BINARY;
4335
4336 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4337
4338 return f;
4339}
4340
4341/*
4342 * Variation on os2emx.popen2
4343 *
Tim Peters11b23062003-04-23 02:39:17 +00004344 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004345 * and stdout+stderr combined as a single pipe.
4346 */
4347
4348static PyObject *
4349os2emx_popen4(PyObject *self, PyObject *args)
4350{
4351 PyObject *f;
4352 int tm = 0;
4353
4354 char *cmdstring;
4355 char *mode = "t";
4356 int bufsize = -1;
4357 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4358 return NULL;
4359
4360 if (*mode == 't')
4361 tm = O_TEXT;
4362 else if (*mode != 'b') {
4363 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4364 return NULL;
4365 } else
4366 tm = O_BINARY;
4367
4368 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4369
4370 return f;
4371}
4372
4373/* a couple of structures for convenient handling of multiple
4374 * file handles and pipes
4375 */
4376struct file_ref
4377{
4378 int handle;
4379 int flags;
4380};
4381
4382struct pipe_ref
4383{
4384 int rd;
4385 int wr;
4386};
4387
4388/* The following code is derived from the win32 code */
4389
4390static PyObject *
4391_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4392{
4393 struct file_ref stdio[3];
4394 struct pipe_ref p_fd[3];
4395 FILE *p_s[3];
Christian Heimesd491d712008-02-01 18:49:26 +00004396 int file_count, i, pipe_err;
4397 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004398 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4399 PyObject *f, *p_f[3];
4400
4401 /* file modes for subsequent fdopen's on pipe handles */
4402 if (mode == O_TEXT)
4403 {
4404 rd_mode = "rt";
4405 wr_mode = "wt";
4406 }
4407 else
4408 {
4409 rd_mode = "rb";
4410 wr_mode = "wb";
4411 }
4412
4413 /* prepare shell references */
4414 if ((shell = getenv("EMXSHELL")) == NULL)
4415 if ((shell = getenv("COMSPEC")) == NULL)
4416 {
4417 errno = ENOENT;
4418 return posix_error();
4419 }
4420
4421 sh_name = _getname(shell);
4422 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4423 opt = "/c";
4424 else
4425 opt = "-c";
4426
4427 /* save current stdio fds + their flags, and set not inheritable */
4428 i = pipe_err = 0;
4429 while (pipe_err >= 0 && i < 3)
4430 {
4431 pipe_err = stdio[i].handle = dup(i);
4432 stdio[i].flags = fcntl(i, F_GETFD, 0);
4433 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4434 i++;
4435 }
4436 if (pipe_err < 0)
4437 {
4438 /* didn't get them all saved - clean up and bail out */
4439 int saved_err = errno;
4440 while (i-- > 0)
4441 {
4442 close(stdio[i].handle);
4443 }
4444 errno = saved_err;
4445 return posix_error();
4446 }
4447
4448 /* create pipe ends */
4449 file_count = 2;
4450 if (n == POPEN_3)
4451 file_count = 3;
4452 i = pipe_err = 0;
4453 while ((pipe_err == 0) && (i < file_count))
4454 pipe_err = pipe((int *)&p_fd[i++]);
4455 if (pipe_err < 0)
4456 {
4457 /* didn't get them all made - clean up and bail out */
4458 while (i-- > 0)
4459 {
4460 close(p_fd[i].wr);
4461 close(p_fd[i].rd);
4462 }
4463 errno = EPIPE;
4464 return posix_error();
4465 }
4466
4467 /* change the actual standard IO streams over temporarily,
4468 * making the retained pipe ends non-inheritable
4469 */
4470 pipe_err = 0;
4471
4472 /* - stdin */
4473 if (dup2(p_fd[0].rd, 0) == 0)
4474 {
4475 close(p_fd[0].rd);
4476 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4477 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4478 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4479 {
4480 close(p_fd[0].wr);
4481 pipe_err = -1;
4482 }
4483 }
4484 else
4485 {
4486 pipe_err = -1;
4487 }
4488
4489 /* - stdout */
4490 if (pipe_err == 0)
4491 {
4492 if (dup2(p_fd[1].wr, 1) == 1)
4493 {
4494 close(p_fd[1].wr);
4495 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4496 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4497 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4498 {
4499 close(p_fd[1].rd);
4500 pipe_err = -1;
4501 }
4502 }
4503 else
4504 {
4505 pipe_err = -1;
4506 }
4507 }
4508
4509 /* - stderr, as required */
4510 if (pipe_err == 0)
4511 switch (n)
4512 {
4513 case POPEN_3:
4514 {
4515 if (dup2(p_fd[2].wr, 2) == 2)
4516 {
4517 close(p_fd[2].wr);
4518 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4519 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4520 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4521 {
4522 close(p_fd[2].rd);
4523 pipe_err = -1;
4524 }
4525 }
4526 else
4527 {
4528 pipe_err = -1;
4529 }
4530 break;
4531 }
4532
4533 case POPEN_4:
4534 {
4535 if (dup2(1, 2) != 2)
4536 {
4537 pipe_err = -1;
4538 }
4539 break;
4540 }
4541 }
4542
4543 /* spawn the child process */
4544 if (pipe_err == 0)
4545 {
4546 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4547 if (pipe_pid == -1)
4548 {
4549 pipe_err = -1;
4550 }
4551 else
4552 {
4553 /* save the PID into the FILE structure
4554 * NOTE: this implementation doesn't actually
4555 * take advantage of this, but do it for
4556 * completeness - AIM Apr01
4557 */
4558 for (i = 0; i < file_count; i++)
4559 p_s[i]->_pid = pipe_pid;
4560 }
4561 }
4562
4563 /* reset standard IO to normal */
4564 for (i = 0; i < 3; i++)
4565 {
4566 dup2(stdio[i].handle, i);
4567 fcntl(i, F_SETFD, stdio[i].flags);
4568 close(stdio[i].handle);
4569 }
4570
4571 /* if any remnant problems, clean up and bail out */
4572 if (pipe_err < 0)
4573 {
4574 for (i = 0; i < 3; i++)
4575 {
4576 close(p_fd[i].rd);
4577 close(p_fd[i].wr);
4578 }
4579 errno = EPIPE;
4580 return posix_error_with_filename(cmdstring);
4581 }
4582
4583 /* build tuple of file objects to return */
4584 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4585 PyFile_SetBufSize(p_f[0], bufsize);
4586 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4587 PyFile_SetBufSize(p_f[1], bufsize);
4588 if (n == POPEN_3)
4589 {
4590 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4591 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004592 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004593 }
4594 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004595 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004596
4597 /*
4598 * Insert the files we've created into the process dictionary
4599 * all referencing the list with the process handle and the
4600 * initial number of files (see description below in _PyPclose).
4601 * Since if _PyPclose later tried to wait on a process when all
4602 * handles weren't closed, it could create a deadlock with the
4603 * child, we spend some energy here to try to ensure that we
4604 * either insert all file handles into the dictionary or none
4605 * at all. It's a little clumsy with the various popen modes
4606 * and variable number of files involved.
4607 */
4608 if (!_PyPopenProcs)
4609 {
4610 _PyPopenProcs = PyDict_New();
4611 }
4612
4613 if (_PyPopenProcs)
4614 {
4615 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4616 int ins_rc[3];
4617
4618 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4619 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4620
4621 procObj = PyList_New(2);
4622 pidObj = PyInt_FromLong((long) pipe_pid);
4623 intObj = PyInt_FromLong((long) file_count);
4624
4625 if (procObj && pidObj && intObj)
4626 {
4627 PyList_SetItem(procObj, 0, pidObj);
4628 PyList_SetItem(procObj, 1, intObj);
4629
4630 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4631 if (fileObj[0])
4632 {
4633 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4634 fileObj[0],
4635 procObj);
4636 }
4637 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4638 if (fileObj[1])
4639 {
4640 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4641 fileObj[1],
4642 procObj);
4643 }
4644 if (file_count >= 3)
4645 {
4646 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4647 if (fileObj[2])
4648 {
4649 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4650 fileObj[2],
4651 procObj);
4652 }
4653 }
4654
4655 if (ins_rc[0] < 0 || !fileObj[0] ||
4656 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4657 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4658 {
4659 /* Something failed - remove any dictionary
4660 * entries that did make it.
4661 */
4662 if (!ins_rc[0] && fileObj[0])
4663 {
4664 PyDict_DelItem(_PyPopenProcs,
4665 fileObj[0]);
4666 }
4667 if (!ins_rc[1] && fileObj[1])
4668 {
4669 PyDict_DelItem(_PyPopenProcs,
4670 fileObj[1]);
4671 }
4672 if (!ins_rc[2] && fileObj[2])
4673 {
4674 PyDict_DelItem(_PyPopenProcs,
4675 fileObj[2]);
4676 }
4677 }
4678 }
Tim Peters11b23062003-04-23 02:39:17 +00004679
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004680 /*
4681 * Clean up our localized references for the dictionary keys
4682 * and value since PyDict_SetItem will Py_INCREF any copies
4683 * that got placed in the dictionary.
4684 */
4685 Py_XDECREF(procObj);
4686 Py_XDECREF(fileObj[0]);
4687 Py_XDECREF(fileObj[1]);
4688 Py_XDECREF(fileObj[2]);
4689 }
4690
4691 /* Child is launched. */
4692 return f;
4693}
4694
4695/*
4696 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4697 * exit code for the child process and return as a result of the close.
4698 *
4699 * This function uses the _PyPopenProcs dictionary in order to map the
4700 * input file pointer to information about the process that was
4701 * originally created by the popen* call that created the file pointer.
4702 * The dictionary uses the file pointer as a key (with one entry
4703 * inserted for each file returned by the original popen* call) and a
4704 * single list object as the value for all files from a single call.
4705 * The list object contains the Win32 process handle at [0], and a file
4706 * count at [1], which is initialized to the total number of file
4707 * handles using that list.
4708 *
4709 * This function closes whichever handle it is passed, and decrements
4710 * the file count in the dictionary for the process handle pointed to
4711 * by this file. On the last close (when the file count reaches zero),
4712 * this function will wait for the child process and then return its
4713 * exit code as the result of the close() operation. This permits the
4714 * files to be closed in any order - it is always the close() of the
4715 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004716 *
4717 * NOTE: This function is currently called with the GIL released.
4718 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004719 */
4720
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004721static int _PyPclose(FILE *file)
4722{
4723 int result;
4724 int exit_code;
Christian Heimesd491d712008-02-01 18:49:26 +00004725 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004726 PyObject *procObj, *pidObj, *intObj, *fileObj;
4727 int file_count;
4728#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004729 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004730#endif
4731
4732 /* Close the file handle first, to ensure it can't block the
4733 * child from exiting if it's the last handle.
4734 */
4735 result = fclose(file);
4736
4737#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004738 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004739#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004740 if (_PyPopenProcs)
4741 {
4742 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4743 (procObj = PyDict_GetItem(_PyPopenProcs,
4744 fileObj)) != NULL &&
4745 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4746 (intObj = PyList_GetItem(procObj,1)) != NULL)
4747 {
4748 pipe_pid = (int) PyInt_AsLong(pidObj);
4749 file_count = (int) PyInt_AsLong(intObj);
4750
4751 if (file_count > 1)
4752 {
4753 /* Still other files referencing process */
4754 file_count--;
4755 PyList_SetItem(procObj,1,
4756 PyInt_FromLong((long) file_count));
4757 }
4758 else
4759 {
4760 /* Last file for this process */
4761 if (result != EOF &&
4762 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4763 {
4764 /* extract exit status */
4765 if (WIFEXITED(exit_code))
4766 {
4767 result = WEXITSTATUS(exit_code);
4768 }
4769 else
4770 {
4771 errno = EPIPE;
4772 result = -1;
4773 }
4774 }
4775 else
4776 {
4777 /* Indicate failure - this will cause the file object
4778 * to raise an I/O error and translate the last
4779 * error code from errno. We do have a problem with
4780 * last errors that overlap the normal errno table,
4781 * but that's a consistent problem with the file object.
4782 */
4783 result = -1;
4784 }
4785 }
4786
4787 /* Remove this file pointer from dictionary */
4788 PyDict_DelItem(_PyPopenProcs, fileObj);
4789
4790 if (PyDict_Size(_PyPopenProcs) == 0)
4791 {
4792 Py_DECREF(_PyPopenProcs);
4793 _PyPopenProcs = NULL;
4794 }
4795
4796 } /* if object retrieval ok */
4797
4798 Py_XDECREF(fileObj);
4799 } /* if _PyPopenProcs */
4800
4801#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004802 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004803#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004804 return result;
4805}
4806
4807#endif /* PYCC_??? */
4808
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004809#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004810
4811/*
4812 * Portable 'popen' replacement for Win32.
4813 *
4814 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4815 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004816 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004817 */
4818
4819#include <malloc.h>
4820#include <io.h>
4821#include <fcntl.h>
4822
4823/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4824#define POPEN_1 1
4825#define POPEN_2 2
4826#define POPEN_3 3
4827#define POPEN_4 4
4828
4829static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004830static int _PyPclose(FILE *file);
4831
4832/*
4833 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004834 * for use when retrieving the process exit code. See _PyPclose() below
4835 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004836 */
4837static PyObject *_PyPopenProcs = NULL;
4838
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004839
4840/* popen that works from a GUI.
4841 *
4842 * The result of this function is a pipe (file) connected to the
4843 * processes stdin or stdout, depending on the requested mode.
4844 */
4845
4846static PyObject *
4847posix_popen(PyObject *self, PyObject *args)
4848{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004849 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004850 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004851
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004852 char *cmdstring;
4853 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004854 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004855 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004856 return NULL;
4857
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004858 if (*mode == 'r')
4859 tm = _O_RDONLY;
4860 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004861 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004862 return NULL;
4863 } else
4864 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004865
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004866 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004867 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004868 return NULL;
4869 }
4870
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004871 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004872 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004873 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004874 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004875 else
4876 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4877
4878 return f;
4879}
4880
4881/* Variation on win32pipe.popen
4882 *
4883 * The result of this function is a pipe (file) connected to the
4884 * process's stdin, and a pipe connected to the process's stdout.
4885 */
4886
4887static PyObject *
4888win32_popen2(PyObject *self, PyObject *args)
4889{
4890 PyObject *f;
4891 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004892
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004893 char *cmdstring;
4894 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004895 int bufsize = -1;
4896 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004897 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004898
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004899 if (*mode == 't')
4900 tm = _O_TEXT;
4901 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004902 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004903 return NULL;
4904 } else
4905 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004906
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004907 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004908 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004909 return NULL;
4910 }
4911
4912 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004913
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004914 return f;
4915}
4916
4917/*
4918 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004919 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004920 * The result of this function is 3 pipes - the process's stdin,
4921 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004922 */
4923
4924static PyObject *
4925win32_popen3(PyObject *self, PyObject *args)
4926{
4927 PyObject *f;
4928 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004929
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004930 char *cmdstring;
4931 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004932 int bufsize = -1;
4933 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004934 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004935
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004936 if (*mode == 't')
4937 tm = _O_TEXT;
4938 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004939 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004940 return NULL;
4941 } else
4942 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004943
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004944 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004945 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004946 return NULL;
4947 }
4948
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004949 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004950
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004951 return f;
4952}
4953
4954/*
4955 * Variation on win32pipe.popen
4956 *
Tim Peters5aa91602002-01-30 05:46:57 +00004957 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004958 * and stdout+stderr combined as a single pipe.
4959 */
4960
4961static PyObject *
4962win32_popen4(PyObject *self, PyObject *args)
4963{
4964 PyObject *f;
4965 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004966
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004967 char *cmdstring;
4968 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004969 int bufsize = -1;
4970 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004971 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004972
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004973 if (*mode == 't')
4974 tm = _O_TEXT;
4975 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004976 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004977 return NULL;
4978 } else
4979 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004980
4981 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004982 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004983 return NULL;
4984 }
4985
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004986 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004987
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004988 return f;
4989}
4990
Mark Hammond08501372001-01-31 07:30:29 +00004991static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004992_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004993 HANDLE hStdin,
4994 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004995 HANDLE hStderr,
4996 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004997{
4998 PROCESS_INFORMATION piProcInfo;
4999 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005000 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005001 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00005002 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005003 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005004 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005005
5006 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00005007 char *comshell;
5008
Tim Peters92e4dd82002-10-05 01:47:34 +00005009 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005010 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00005011 /* x < i, so x fits into an integer */
5012 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005013
5014 /* Explicitly check if we are using COMMAND.COM. If we are
5015 * then use the w9xpopen hack.
5016 */
5017 comshell = s1 + x;
5018 while (comshell >= s1 && *comshell != '\\')
5019 --comshell;
5020 ++comshell;
5021
5022 if (GetVersion() < 0x80000000 &&
5023 _stricmp(comshell, "command.com") != 0) {
5024 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005025 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00005026 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005027 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00005028 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005029 }
5030 else {
5031 /*
Tim Peters402d5982001-08-27 06:37:48 +00005032 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5033 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005034 */
Mark Hammond08501372001-01-31 07:30:29 +00005035 char modulepath[_MAX_PATH];
5036 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005037 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00005038 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005039 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005040 x = i+1;
5041 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00005042 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00005043 strncat(modulepath,
5044 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00005045 (sizeof(modulepath)/sizeof(modulepath[0]))
5046 -strlen(modulepath));
5047 if (stat(modulepath, &statinfo) != 0) {
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005048 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
Tim Peters5aa91602002-01-30 05:46:57 +00005049 /* Eeek - file-not-found - possibly an embedding
5050 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00005051 */
Tim Peters5aa91602002-01-30 05:46:57 +00005052 strncpy(modulepath,
5053 Py_GetExecPrefix(),
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005054 mplen);
5055 modulepath[mplen-1] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00005056 if (modulepath[strlen(modulepath)-1] != '\\')
5057 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00005058 strncat(modulepath,
5059 szConsoleSpawn,
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00005060 mplen-strlen(modulepath));
Mark Hammond08501372001-01-31 07:30:29 +00005061 /* No where else to look - raise an easily identifiable
5062 error, rather than leaving Windows to report
5063 "file not found" - as the user is probably blissfully
5064 unaware this shim EXE is used, and it will confuse them.
5065 (well, it confused me for a while ;-)
5066 */
5067 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00005068 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00005069 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00005070 "for popen to work with your shell "
5071 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00005072 szConsoleSpawn);
5073 return FALSE;
5074 }
5075 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005076 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00005077 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005078 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005079
Tim Peters92e4dd82002-10-05 01:47:34 +00005080 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005081 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005082 /* To maintain correct argument passing semantics,
5083 we pass the command-line as it stands, and allow
5084 quoting to be applied. w9xpopen.exe will then
5085 use its argv vector, and re-quote the necessary
5086 args for the ultimate child process.
5087 */
Tim Peters75cdad52001-11-28 22:07:30 +00005088 PyOS_snprintf(
5089 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005090 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005091 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005092 s1,
5093 s3,
5094 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005095 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00005096 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005097 dialog:
5098 "Your program accessed mem currently in use at xxx"
5099 and a hopeful warning about the stability of your
5100 system.
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00005101 Cost is Ctrl+C won't kill children, but anyone
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005102 who cares can have a go!
5103 */
5104 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005105 }
5106 }
5107
5108 /* Could be an else here to try cmd.exe / command.com in the path
5109 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00005110 else {
Tim Peters402d5982001-08-27 06:37:48 +00005111 PyErr_SetString(PyExc_RuntimeError,
5112 "Cannot locate a COMSPEC environment variable to "
5113 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00005114 return FALSE;
5115 }
Tim Peters5aa91602002-01-30 05:46:57 +00005116
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005117 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5118 siStartInfo.cb = sizeof(STARTUPINFO);
5119 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5120 siStartInfo.hStdInput = hStdin;
5121 siStartInfo.hStdOutput = hStdout;
5122 siStartInfo.hStdError = hStderr;
5123 siStartInfo.wShowWindow = SW_HIDE;
5124
5125 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005126 s2,
5127 NULL,
5128 NULL,
5129 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005130 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005131 NULL,
5132 NULL,
5133 &siStartInfo,
5134 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005135 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005136 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005137
Mark Hammondb37a3732000-08-14 04:47:33 +00005138 /* Return process handle */
5139 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005140 return TRUE;
5141 }
Tim Peters402d5982001-08-27 06:37:48 +00005142 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005143 return FALSE;
5144}
5145
5146/* The following code is based off of KB: Q190351 */
5147
5148static PyObject *
5149_PyPopen(char *cmdstring, int mode, int n)
5150{
5151 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5152 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00005153 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005154
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005155 SECURITY_ATTRIBUTES saAttr;
5156 BOOL fSuccess;
5157 int fd1, fd2, fd3;
5158 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00005159 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005160 PyObject *f;
5161
5162 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5163 saAttr.bInheritHandle = TRUE;
5164 saAttr.lpSecurityDescriptor = NULL;
5165
5166 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5167 return win32_error("CreatePipe", NULL);
5168
5169 /* Create new output read handle and the input write handle. Set
5170 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005171 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005172 * being created. */
5173 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005174 GetCurrentProcess(), &hChildStdinWrDup, 0,
5175 FALSE,
5176 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005177 if (!fSuccess)
5178 return win32_error("DuplicateHandle", NULL);
5179
5180 /* Close the inheritable version of ChildStdin
5181 that we're using. */
5182 CloseHandle(hChildStdinWr);
5183
5184 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5185 return win32_error("CreatePipe", NULL);
5186
5187 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005188 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5189 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005190 if (!fSuccess)
5191 return win32_error("DuplicateHandle", NULL);
5192
5193 /* Close the inheritable version of ChildStdout
5194 that we're using. */
5195 CloseHandle(hChildStdoutRd);
5196
5197 if (n != POPEN_4) {
5198 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5199 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005200 fSuccess = DuplicateHandle(GetCurrentProcess(),
5201 hChildStderrRd,
5202 GetCurrentProcess(),
5203 &hChildStderrRdDup, 0,
5204 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005205 if (!fSuccess)
5206 return win32_error("DuplicateHandle", NULL);
5207 /* Close the inheritable version of ChildStdErr that we're using. */
5208 CloseHandle(hChildStderrRd);
5209 }
Tim Peters5aa91602002-01-30 05:46:57 +00005210
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005211 switch (n) {
5212 case POPEN_1:
5213 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5214 case _O_WRONLY | _O_TEXT:
5215 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005216 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005217 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005218 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005219 PyFile_SetBufSize(f, 0);
5220 /* We don't care about these pipes anymore, so close them. */
5221 CloseHandle(hChildStdoutRdDup);
5222 CloseHandle(hChildStderrRdDup);
5223 break;
5224
5225 case _O_RDONLY | _O_TEXT:
5226 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005227 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005228 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005229 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005230 PyFile_SetBufSize(f, 0);
5231 /* We don't care about these pipes anymore, so close them. */
5232 CloseHandle(hChildStdinWrDup);
5233 CloseHandle(hChildStderrRdDup);
5234 break;
5235
5236 case _O_RDONLY | _O_BINARY:
5237 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005238 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005239 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005240 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005241 PyFile_SetBufSize(f, 0);
5242 /* We don't care about these pipes anymore, so close them. */
5243 CloseHandle(hChildStdinWrDup);
5244 CloseHandle(hChildStderrRdDup);
5245 break;
5246
5247 case _O_WRONLY | _O_BINARY:
5248 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005249 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005250 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005251 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005252 PyFile_SetBufSize(f, 0);
5253 /* We don't care about these pipes anymore, so close them. */
5254 CloseHandle(hChildStdoutRdDup);
5255 CloseHandle(hChildStderrRdDup);
5256 break;
5257 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005258 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005259 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005260
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005261 case POPEN_2:
5262 case POPEN_4:
5263 {
5264 char *m1, *m2;
5265 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005266
Tim Peters7dca21e2002-08-19 00:42:29 +00005267 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005268 m1 = "r";
5269 m2 = "w";
5270 } else {
5271 m1 = "rb";
5272 m2 = "wb";
5273 }
5274
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005275 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005276 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005277 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005278 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005279 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005280 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005281 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005282 PyFile_SetBufSize(p2, 0);
5283
5284 if (n != 4)
5285 CloseHandle(hChildStderrRdDup);
5286
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005287 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005288 Py_XDECREF(p1);
5289 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005290 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005291 break;
5292 }
Tim Peters5aa91602002-01-30 05:46:57 +00005293
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005294 case POPEN_3:
5295 {
5296 char *m1, *m2;
5297 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005298
Tim Peters7dca21e2002-08-19 00:42:29 +00005299 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005300 m1 = "r";
5301 m2 = "w";
5302 } else {
5303 m1 = "rb";
5304 m2 = "wb";
5305 }
5306
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005307 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005308 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005309 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005310 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005311 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005312 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005313 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005314 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5315 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005316 PyFile_SetBufSize(p1, 0);
5317 PyFile_SetBufSize(p2, 0);
5318 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005319 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005320 Py_XDECREF(p1);
5321 Py_XDECREF(p2);
5322 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005323 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005324 break;
5325 }
5326 }
5327
5328 if (n == POPEN_4) {
5329 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005330 hChildStdinRd,
5331 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005332 hChildStdoutWr,
5333 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005334 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005335 }
5336 else {
5337 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005338 hChildStdinRd,
5339 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005340 hChildStderrWr,
5341 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005342 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005343 }
5344
Mark Hammondb37a3732000-08-14 04:47:33 +00005345 /*
5346 * Insert the files we've created into the process dictionary
5347 * all referencing the list with the process handle and the
5348 * initial number of files (see description below in _PyPclose).
5349 * Since if _PyPclose later tried to wait on a process when all
5350 * handles weren't closed, it could create a deadlock with the
5351 * child, we spend some energy here to try to ensure that we
5352 * either insert all file handles into the dictionary or none
5353 * at all. It's a little clumsy with the various popen modes
5354 * and variable number of files involved.
5355 */
5356 if (!_PyPopenProcs) {
5357 _PyPopenProcs = PyDict_New();
5358 }
5359
5360 if (_PyPopenProcs) {
5361 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5362 int ins_rc[3];
5363
5364 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5365 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5366
5367 procObj = PyList_New(2);
5368 hProcessObj = PyLong_FromVoidPtr(hProcess);
5369 intObj = PyInt_FromLong(file_count);
5370
5371 if (procObj && hProcessObj && intObj) {
5372 PyList_SetItem(procObj,0,hProcessObj);
5373 PyList_SetItem(procObj,1,intObj);
5374
5375 fileObj[0] = PyLong_FromVoidPtr(f1);
5376 if (fileObj[0]) {
5377 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5378 fileObj[0],
5379 procObj);
5380 }
5381 if (file_count >= 2) {
5382 fileObj[1] = PyLong_FromVoidPtr(f2);
5383 if (fileObj[1]) {
5384 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5385 fileObj[1],
5386 procObj);
5387 }
5388 }
5389 if (file_count >= 3) {
5390 fileObj[2] = PyLong_FromVoidPtr(f3);
5391 if (fileObj[2]) {
5392 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5393 fileObj[2],
5394 procObj);
5395 }
5396 }
5397
5398 if (ins_rc[0] < 0 || !fileObj[0] ||
5399 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5400 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5401 /* Something failed - remove any dictionary
5402 * entries that did make it.
5403 */
5404 if (!ins_rc[0] && fileObj[0]) {
5405 PyDict_DelItem(_PyPopenProcs,
5406 fileObj[0]);
5407 }
5408 if (!ins_rc[1] && fileObj[1]) {
5409 PyDict_DelItem(_PyPopenProcs,
5410 fileObj[1]);
5411 }
5412 if (!ins_rc[2] && fileObj[2]) {
5413 PyDict_DelItem(_PyPopenProcs,
5414 fileObj[2]);
5415 }
5416 }
5417 }
Tim Peters5aa91602002-01-30 05:46:57 +00005418
Mark Hammondb37a3732000-08-14 04:47:33 +00005419 /*
5420 * Clean up our localized references for the dictionary keys
5421 * and value since PyDict_SetItem will Py_INCREF any copies
5422 * that got placed in the dictionary.
5423 */
5424 Py_XDECREF(procObj);
5425 Py_XDECREF(fileObj[0]);
5426 Py_XDECREF(fileObj[1]);
5427 Py_XDECREF(fileObj[2]);
5428 }
5429
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005430 /* Child is launched. Close the parents copy of those pipe
5431 * handles that only the child should have open. You need to
5432 * make sure that no handles to the write end of the output pipe
5433 * are maintained in this process or else the pipe will not close
5434 * when the child process exits and the ReadFile will hang. */
5435
5436 if (!CloseHandle(hChildStdinRd))
5437 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005438
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005439 if (!CloseHandle(hChildStdoutWr))
5440 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005441
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005442 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5443 return win32_error("CloseHandle", NULL);
5444
5445 return f;
5446}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005447
5448/*
5449 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5450 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005451 *
5452 * This function uses the _PyPopenProcs dictionary in order to map the
5453 * input file pointer to information about the process that was
5454 * originally created by the popen* call that created the file pointer.
5455 * The dictionary uses the file pointer as a key (with one entry
5456 * inserted for each file returned by the original popen* call) and a
5457 * single list object as the value for all files from a single call.
5458 * The list object contains the Win32 process handle at [0], and a file
5459 * count at [1], which is initialized to the total number of file
5460 * handles using that list.
5461 *
5462 * This function closes whichever handle it is passed, and decrements
5463 * the file count in the dictionary for the process handle pointed to
5464 * by this file. On the last close (when the file count reaches zero),
5465 * this function will wait for the child process and then return its
5466 * exit code as the result of the close() operation. This permits the
5467 * files to be closed in any order - it is always the close() of the
5468 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005469 *
5470 * NOTE: This function is currently called with the GIL released.
5471 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005472 */
Tim Peters736aa322000-09-01 06:51:24 +00005473
Fredrik Lundh56055a42000-07-23 19:47:12 +00005474static int _PyPclose(FILE *file)
5475{
Fredrik Lundh20318932000-07-26 17:29:12 +00005476 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005477 DWORD exit_code;
5478 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005479 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5480 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005481#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005482 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005483#endif
5484
Fredrik Lundh20318932000-07-26 17:29:12 +00005485 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005486 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005487 */
5488 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005489#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005490 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005491#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005492 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005493 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5494 (procObj = PyDict_GetItem(_PyPopenProcs,
5495 fileObj)) != NULL &&
5496 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5497 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5498
5499 hProcess = PyLong_AsVoidPtr(hProcessObj);
5500 file_count = PyInt_AsLong(intObj);
5501
5502 if (file_count > 1) {
5503 /* Still other files referencing process */
5504 file_count--;
5505 PyList_SetItem(procObj,1,
5506 PyInt_FromLong(file_count));
5507 } else {
5508 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005509 if (result != EOF &&
5510 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5511 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005512 /* Possible truncation here in 16-bit environments, but
5513 * real exit codes are just the lower byte in any event.
5514 */
5515 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005516 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005517 /* Indicate failure - this will cause the file object
5518 * to raise an I/O error and translate the last Win32
5519 * error code from errno. We do have a problem with
5520 * last errors that overlap the normal errno table,
5521 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005522 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005523 if (result != EOF) {
5524 /* If the error wasn't from the fclose(), then
5525 * set errno for the file object error handling.
5526 */
5527 errno = GetLastError();
5528 }
5529 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005530 }
5531
5532 /* Free up the native handle at this point */
5533 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005534 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005535
Mark Hammondb37a3732000-08-14 04:47:33 +00005536 /* Remove this file pointer from dictionary */
5537 PyDict_DelItem(_PyPopenProcs, fileObj);
5538
5539 if (PyDict_Size(_PyPopenProcs) == 0) {
5540 Py_DECREF(_PyPopenProcs);
5541 _PyPopenProcs = NULL;
5542 }
5543
5544 } /* if object retrieval ok */
5545
5546 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005547 } /* if _PyPopenProcs */
5548
Tim Peters736aa322000-09-01 06:51:24 +00005549#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005550 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005551#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005552 return result;
5553}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005554
5555#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005556static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005557posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005558{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005559 char *name;
5560 char *mode = "r";
5561 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005562 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005563 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005564 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005565 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005566 /* Strip mode of binary or text modifiers */
5567 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5568 mode = "r";
5569 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5570 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005571 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005572 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005573 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005574 if (fp == NULL)
5575 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005576 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005577 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005578 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005579 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005580}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005581
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005582#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005583#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005584
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005585
Guido van Rossumb6775db1994-08-01 11:34:53 +00005586#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005587PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005588"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005589Set the current process's user id.");
5590
Barry Warsaw53699e91996-12-10 23:23:01 +00005591static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005592posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005593{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005594 long uid_arg;
5595 uid_t uid;
5596 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005597 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005598 uid = uid_arg;
5599 if (uid != uid_arg) {
5600 PyErr_SetString(PyExc_OverflowError, "user id too big");
5601 return NULL;
5602 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005603 if (setuid(uid) < 0)
5604 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005605 Py_INCREF(Py_None);
5606 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005607}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005608#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005610
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005611#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005612PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005613"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005614Set the current process's effective user id.");
5615
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005616static PyObject *
5617posix_seteuid (PyObject *self, PyObject *args)
5618{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005619 long euid_arg;
5620 uid_t euid;
5621 if (!PyArg_ParseTuple(args, "l", &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005622 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005623 euid = euid_arg;
5624 if (euid != euid_arg) {
5625 PyErr_SetString(PyExc_OverflowError, "user id too big");
5626 return NULL;
5627 }
5628 if (seteuid(euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005629 return posix_error();
5630 } else {
5631 Py_INCREF(Py_None);
5632 return Py_None;
5633 }
5634}
5635#endif /* HAVE_SETEUID */
5636
5637#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005638PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005639"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005640Set the current process's effective group id.");
5641
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005642static PyObject *
5643posix_setegid (PyObject *self, PyObject *args)
5644{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005645 long egid_arg;
5646 gid_t egid;
5647 if (!PyArg_ParseTuple(args, "l", &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005648 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005649 egid = egid_arg;
5650 if (egid != egid_arg) {
5651 PyErr_SetString(PyExc_OverflowError, "group id too big");
5652 return NULL;
5653 }
5654 if (setegid(egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005655 return posix_error();
5656 } else {
5657 Py_INCREF(Py_None);
5658 return Py_None;
5659 }
5660}
5661#endif /* HAVE_SETEGID */
5662
5663#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005664PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005665"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005666Set the current process's real and effective user ids.");
5667
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005668static PyObject *
5669posix_setreuid (PyObject *self, PyObject *args)
5670{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005671 long ruid_arg, euid_arg;
5672 uid_t ruid, euid;
5673 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005674 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005675 ruid = ruid_arg;
5676 euid = euid_arg;
5677 if (euid != euid_arg || ruid != ruid_arg) {
5678 PyErr_SetString(PyExc_OverflowError, "user id too big");
5679 return NULL;
5680 }
5681 if (setreuid(ruid, euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005682 return posix_error();
5683 } else {
5684 Py_INCREF(Py_None);
5685 return Py_None;
5686 }
5687}
5688#endif /* HAVE_SETREUID */
5689
5690#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005691PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005692"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005693Set the current process's real and effective group ids.");
5694
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005695static PyObject *
5696posix_setregid (PyObject *self, PyObject *args)
5697{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005698 long rgid_arg, egid_arg;
5699 gid_t rgid, egid;
5700 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005701 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005702 rgid = rgid_arg;
5703 egid = egid_arg;
5704 if (egid != egid_arg || rgid != rgid_arg) {
5705 PyErr_SetString(PyExc_OverflowError, "group id too big");
5706 return NULL;
5707 }
5708 if (setregid(rgid, egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005709 return posix_error();
5710 } else {
5711 Py_INCREF(Py_None);
5712 return Py_None;
5713 }
5714}
5715#endif /* HAVE_SETREGID */
5716
Guido van Rossumb6775db1994-08-01 11:34:53 +00005717#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005718PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005719"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005720Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005721
Barry Warsaw53699e91996-12-10 23:23:01 +00005722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005723posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005724{
Gregory P. Smith6d307932009-04-05 23:43:58 +00005725 long gid_arg;
5726 gid_t gid;
5727 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005728 return NULL;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005729 gid = gid_arg;
5730 if (gid != gid_arg) {
5731 PyErr_SetString(PyExc_OverflowError, "group id too big");
5732 return NULL;
5733 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005734 if (setgid(gid) < 0)
5735 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005736 Py_INCREF(Py_None);
5737 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005738}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005739#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005740
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005741#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005742PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005743"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005744Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005745
5746static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005747posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005748{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005749 int i, len;
5750 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005751
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005752 if (!PySequence_Check(groups)) {
5753 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5754 return NULL;
5755 }
5756 len = PySequence_Size(groups);
5757 if (len > MAX_GROUPS) {
5758 PyErr_SetString(PyExc_ValueError, "too many groups");
5759 return NULL;
5760 }
5761 for(i = 0; i < len; i++) {
5762 PyObject *elem;
5763 elem = PySequence_GetItem(groups, i);
5764 if (!elem)
5765 return NULL;
5766 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005767 if (!PyLong_Check(elem)) {
5768 PyErr_SetString(PyExc_TypeError,
5769 "groups must be integers");
5770 Py_DECREF(elem);
5771 return NULL;
5772 } else {
5773 unsigned long x = PyLong_AsUnsignedLong(elem);
5774 if (PyErr_Occurred()) {
5775 PyErr_SetString(PyExc_TypeError,
5776 "group id too big");
5777 Py_DECREF(elem);
5778 return NULL;
5779 }
5780 grouplist[i] = x;
Gregory P. Smith6d307932009-04-05 23:43:58 +00005781 /* read back to see if it fits in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00005782 if (grouplist[i] != x) {
5783 PyErr_SetString(PyExc_TypeError,
5784 "group id too big");
5785 Py_DECREF(elem);
5786 return NULL;
5787 }
5788 }
5789 } else {
5790 long x = PyInt_AsLong(elem);
5791 grouplist[i] = x;
5792 if (grouplist[i] != x) {
5793 PyErr_SetString(PyExc_TypeError,
5794 "group id too big");
5795 Py_DECREF(elem);
5796 return NULL;
5797 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005798 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005799 Py_DECREF(elem);
5800 }
5801
5802 if (setgroups(len, grouplist) < 0)
5803 return posix_error();
5804 Py_INCREF(Py_None);
5805 return Py_None;
5806}
5807#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005808
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005809#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005810static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005811wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005812{
5813 PyObject *result;
5814 static PyObject *struct_rusage;
5815
5816 if (pid == -1)
5817 return posix_error();
5818
5819 if (struct_rusage == NULL) {
Christian Heimes000a0742008-01-03 22:16:32 +00005820 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Neal Norwitz05a45592006-03-20 06:30:08 +00005821 if (m == NULL)
5822 return NULL;
5823 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5824 Py_DECREF(m);
5825 if (struct_rusage == NULL)
5826 return NULL;
5827 }
5828
5829 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5830 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5831 if (!result)
5832 return NULL;
5833
5834#ifndef doubletime
5835#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5836#endif
5837
5838 PyStructSequence_SET_ITEM(result, 0,
5839 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5840 PyStructSequence_SET_ITEM(result, 1,
5841 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5842#define SET_INT(result, index, value)\
5843 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5844 SET_INT(result, 2, ru->ru_maxrss);
5845 SET_INT(result, 3, ru->ru_ixrss);
5846 SET_INT(result, 4, ru->ru_idrss);
5847 SET_INT(result, 5, ru->ru_isrss);
5848 SET_INT(result, 6, ru->ru_minflt);
5849 SET_INT(result, 7, ru->ru_majflt);
5850 SET_INT(result, 8, ru->ru_nswap);
5851 SET_INT(result, 9, ru->ru_inblock);
5852 SET_INT(result, 10, ru->ru_oublock);
5853 SET_INT(result, 11, ru->ru_msgsnd);
5854 SET_INT(result, 12, ru->ru_msgrcv);
5855 SET_INT(result, 13, ru->ru_nsignals);
5856 SET_INT(result, 14, ru->ru_nvcsw);
5857 SET_INT(result, 15, ru->ru_nivcsw);
5858#undef SET_INT
5859
5860 if (PyErr_Occurred()) {
5861 Py_DECREF(result);
5862 return NULL;
5863 }
5864
Neal Norwitz9b00a562006-03-20 08:47:12 +00005865 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005866}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005867#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005868
5869#ifdef HAVE_WAIT3
5870PyDoc_STRVAR(posix_wait3__doc__,
5871"wait3(options) -> (pid, status, rusage)\n\n\
5872Wait for completion of a child process.");
5873
5874static PyObject *
5875posix_wait3(PyObject *self, PyObject *args)
5876{
Christian Heimesd491d712008-02-01 18:49:26 +00005877 pid_t pid;
5878 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005879 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005880 WAIT_TYPE status;
5881 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005882
5883 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5884 return NULL;
5885
5886 Py_BEGIN_ALLOW_THREADS
5887 pid = wait3(&status, options, &ru);
5888 Py_END_ALLOW_THREADS
5889
Neal Norwitzd5a37542006-03-20 06:48:34 +00005890 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005891}
5892#endif /* HAVE_WAIT3 */
5893
5894#ifdef HAVE_WAIT4
5895PyDoc_STRVAR(posix_wait4__doc__,
5896"wait4(pid, options) -> (pid, status, rusage)\n\n\
5897Wait for completion of a given child process.");
5898
5899static PyObject *
5900posix_wait4(PyObject *self, PyObject *args)
5901{
Christian Heimesd491d712008-02-01 18:49:26 +00005902 pid_t pid;
5903 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005904 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005905 WAIT_TYPE status;
5906 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005907
5908 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5909 return NULL;
5910
5911 Py_BEGIN_ALLOW_THREADS
5912 pid = wait4(pid, &status, options, &ru);
5913 Py_END_ALLOW_THREADS
5914
Neal Norwitzd5a37542006-03-20 06:48:34 +00005915 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005916}
5917#endif /* HAVE_WAIT4 */
5918
Guido van Rossumb6775db1994-08-01 11:34:53 +00005919#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005920PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005921"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005922Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005923
Barry Warsaw53699e91996-12-10 23:23:01 +00005924static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005925posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005926{
Christian Heimesd491d712008-02-01 18:49:26 +00005927 pid_t pid;
5928 int options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005929 WAIT_TYPE status;
5930 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005931
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005932 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005933 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005934 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005935 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005936 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005937 if (pid == -1)
5938 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005939
5940 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005941}
5942
Tim Petersab034fa2002-02-01 11:27:43 +00005943#elif defined(HAVE_CWAIT)
5944
5945/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005946PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005947"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005948"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005949
5950static PyObject *
5951posix_waitpid(PyObject *self, PyObject *args)
5952{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005953 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005954 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005955
5956 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5957 return NULL;
5958 Py_BEGIN_ALLOW_THREADS
5959 pid = _cwait(&status, pid, options);
5960 Py_END_ALLOW_THREADS
5961 if (pid == -1)
5962 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005963
5964 /* shift the status left a byte so this is more like the POSIX waitpid */
5965 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005966}
5967#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005968
Guido van Rossumad0ee831995-03-01 10:34:45 +00005969#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005970PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005971"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005972Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005973
Barry Warsaw53699e91996-12-10 23:23:01 +00005974static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005975posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005976{
Christian Heimesd491d712008-02-01 18:49:26 +00005977 pid_t pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005978 WAIT_TYPE status;
5979 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005980
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005981 Py_BEGIN_ALLOW_THREADS
5982 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005983 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005984 if (pid == -1)
5985 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005986
5987 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005988}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005989#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005990
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005991
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005992PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005993"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005994Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005995
Barry Warsaw53699e91996-12-10 23:23:01 +00005996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005997posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005998{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005999#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006000 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006001#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006002#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00006003 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006004#else
6005 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
6006#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006007#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006008}
6009
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006010
Guido van Rossumb6775db1994-08-01 11:34:53 +00006011#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006012PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006013"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006014Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006015
Barry Warsaw53699e91996-12-10 23:23:01 +00006016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006017posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006018{
Ronald Oussoren10168f22006-10-22 10:45:18 +00006019 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00006020 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00006021 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006022 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006023#ifdef Py_USING_UNICODE
6024 int arg_is_unicode = 0;
6025#endif
6026
6027 if (!PyArg_ParseTuple(args, "et:readlink",
6028 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006029 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006030#ifdef Py_USING_UNICODE
6031 v = PySequence_GetItem(args, 0);
Neal Norwitz91a57212007-08-12 17:11:13 +00006032 if (v == NULL) {
6033 PyMem_Free(path);
6034 return NULL;
6035 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006036
6037 if (PyUnicode_Check(v)) {
6038 arg_is_unicode = 1;
6039 }
6040 Py_DECREF(v);
6041#endif
6042
Barry Warsaw53699e91996-12-10 23:23:01 +00006043 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00006044 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00006045 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006046 if (n < 0)
Neal Norwitz91a57212007-08-12 17:11:13 +00006047 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006048
Neal Norwitz91a57212007-08-12 17:11:13 +00006049 PyMem_Free(path);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006050 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006051#ifdef Py_USING_UNICODE
6052 if (arg_is_unicode) {
6053 PyObject *w;
6054
6055 w = PyUnicode_FromEncodedObject(v,
6056 Py_FileSystemDefaultEncoding,
6057 "strict");
6058 if (w != NULL) {
6059 Py_DECREF(v);
6060 v = w;
6061 }
6062 else {
6063 /* fall back to the original byte string, as
6064 discussed in patch #683592 */
6065 PyErr_Clear();
6066 }
6067 }
6068#endif
6069 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006070}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006071#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006072
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006073
Guido van Rossumb6775db1994-08-01 11:34:53 +00006074#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006075PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006076"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006077Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006078
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006079static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006080posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006081{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00006082 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006083}
6084#endif /* HAVE_SYMLINK */
6085
6086
6087#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006088#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6089static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006090system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006091{
6092 ULONG value = 0;
6093
6094 Py_BEGIN_ALLOW_THREADS
6095 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6096 Py_END_ALLOW_THREADS
6097
6098 return value;
6099}
6100
6101static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006102posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006103{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006104 /* Currently Only Uptime is Provided -- Others Later */
6105 return Py_BuildValue("ddddd",
6106 (double)0 /* t.tms_utime / HZ */,
6107 (double)0 /* t.tms_stime / HZ */,
6108 (double)0 /* t.tms_cutime / HZ */,
6109 (double)0 /* t.tms_cstime / HZ */,
6110 (double)system_uptime() / 1000);
6111}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006112#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006113#define NEED_TICKS_PER_SECOND
6114static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006115static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006116posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006117{
6118 struct tms t;
6119 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00006120 errno = 0;
6121 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00006122 if (c == (clock_t) -1)
6123 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006124 return Py_BuildValue("ddddd",
Martin v. Löwis03824e42008-12-29 18:17:34 +00006125 (double)t.tms_utime / ticks_per_second,
6126 (double)t.tms_stime / ticks_per_second,
6127 (double)t.tms_cutime / ticks_per_second,
6128 (double)t.tms_cstime / ticks_per_second,
6129 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006130}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006131#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006132#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006133
6134
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006135#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006136#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006137static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006138posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006139{
6140 FILETIME create, exit, kernel, user;
6141 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006142 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006143 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6144 /* The fields of a FILETIME structure are the hi and lo part
6145 of a 64-bit value expressed in 100 nanosecond units.
6146 1e7 is one second in such units; 1e-7 the inverse.
6147 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6148 */
Barry Warsaw53699e91996-12-10 23:23:01 +00006149 return Py_BuildValue(
6150 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006151 (double)(user.dwHighDateTime*429.4967296 +
6152 user.dwLowDateTime*1e-7),
Georg Brandl0a40ffb2008-02-13 07:20:22 +00006153 (double)(kernel.dwHighDateTime*429.4967296 +
6154 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00006155 (double)0,
6156 (double)0,
6157 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006158}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006159#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006160
6161#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006162PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006163"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006164Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006165#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006166
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006167
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006168#ifdef HAVE_GETSID
6169PyDoc_STRVAR(posix_getsid__doc__,
6170"getsid(pid) -> sid\n\n\
6171Call the system call getsid().");
6172
6173static PyObject *
6174posix_getsid(PyObject *self, PyObject *args)
6175{
Christian Heimesd491d712008-02-01 18:49:26 +00006176 pid_t pid;
6177 int sid;
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006178 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
6179 return NULL;
6180 sid = getsid(pid);
6181 if (sid < 0)
6182 return posix_error();
6183 return PyInt_FromLong((long)sid);
6184}
6185#endif /* HAVE_GETSID */
6186
6187
Guido van Rossumb6775db1994-08-01 11:34:53 +00006188#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006189PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006190"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006191Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006192
Barry Warsaw53699e91996-12-10 23:23:01 +00006193static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006194posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006195{
Guido van Rossum687dd131993-05-17 08:34:16 +00006196 if (setsid() < 0)
6197 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006198 Py_INCREF(Py_None);
6199 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006200}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006201#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006202
Guido van Rossumb6775db1994-08-01 11:34:53 +00006203#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006204PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006205"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006206Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006207
Barry Warsaw53699e91996-12-10 23:23:01 +00006208static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006209posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006210{
Christian Heimesd491d712008-02-01 18:49:26 +00006211 pid_t pid;
6212 int pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006213 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00006214 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006215 if (setpgid(pid, pgrp) < 0)
6216 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006217 Py_INCREF(Py_None);
6218 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006219}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006220#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006221
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006222
Guido van Rossumb6775db1994-08-01 11:34:53 +00006223#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006224PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006225"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006226Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006227
Barry Warsaw53699e91996-12-10 23:23:01 +00006228static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006229posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006230{
Christian Heimese6a80742008-02-03 19:51:13 +00006231 int fd;
6232 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006233 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006234 return NULL;
6235 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006236 if (pgid < 0)
6237 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006238 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006239}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006240#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006241
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006242
Guido van Rossumb6775db1994-08-01 11:34:53 +00006243#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006244PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006245"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006246Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006247
Barry Warsaw53699e91996-12-10 23:23:01 +00006248static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006249posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006250{
6251 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006252 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006253 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006254 if (tcsetpgrp(fd, pgid) < 0)
6255 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00006256 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00006257 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006258}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006259#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006260
Guido van Rossum687dd131993-05-17 08:34:16 +00006261/* Functions acting on file descriptors */
6262
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006263PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006264"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006265Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006266
Barry Warsaw53699e91996-12-10 23:23:01 +00006267static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006268posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006269{
Mark Hammondef8b6542001-05-13 08:04:26 +00006270 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006271 int flag;
6272 int mode = 0777;
6273 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006274
6275#ifdef MS_WINDOWS
6276 if (unicode_file_names()) {
6277 PyUnicodeObject *po;
6278 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6279 Py_BEGIN_ALLOW_THREADS
6280 /* PyUnicode_AS_UNICODE OK without thread
6281 lock as it is a simple dereference. */
6282 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6283 Py_END_ALLOW_THREADS
6284 if (fd < 0)
6285 return posix_error();
6286 return PyInt_FromLong((long)fd);
6287 }
6288 /* Drop the argument parsing error as narrow strings
6289 are also valid. */
6290 PyErr_Clear();
6291 }
6292#endif
6293
Tim Peters5aa91602002-01-30 05:46:57 +00006294 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006295 Py_FileSystemDefaultEncoding, &file,
6296 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006297 return NULL;
6298
Barry Warsaw53699e91996-12-10 23:23:01 +00006299 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006300 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006301 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006302 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006303 return posix_error_with_allocated_filename(file);
6304 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006305 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006306}
6307
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006308
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006309PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006310"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006311Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006312
Barry Warsaw53699e91996-12-10 23:23:01 +00006313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006314posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006315{
6316 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006317 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006318 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006319 if (!_PyVerify_fd(fd))
6320 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006321 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006322 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006323 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006324 if (res < 0)
6325 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006326 Py_INCREF(Py_None);
6327 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006328}
6329
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006330
Georg Brandl309501a2008-01-19 20:22:13 +00006331PyDoc_STRVAR(posix_closerange__doc__,
6332"closerange(fd_low, fd_high)\n\n\
6333Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6334
6335static PyObject *
6336posix_closerange(PyObject *self, PyObject *args)
6337{
6338 int fd_from, fd_to, i;
6339 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6340 return NULL;
6341 Py_BEGIN_ALLOW_THREADS
6342 for (i = fd_from; i < fd_to; i++)
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006343 if (_PyVerify_fd(i))
6344 close(i);
Georg Brandl309501a2008-01-19 20:22:13 +00006345 Py_END_ALLOW_THREADS
6346 Py_RETURN_NONE;
6347}
6348
6349
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006350PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006351"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006352Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006353
Barry Warsaw53699e91996-12-10 23:23:01 +00006354static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006355posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006356{
6357 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006358 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006359 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006360 if (!_PyVerify_fd(fd))
6361 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006362 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006363 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006364 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006365 if (fd < 0)
6366 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006367 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006368}
6369
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006370
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006371PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006372"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006373Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006374
Barry Warsaw53699e91996-12-10 23:23:01 +00006375static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006376posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006377{
6378 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006379 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006380 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006381 if (!_PyVerify_fd_dup2(fd, fd2))
6382 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006383 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006384 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006385 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006386 if (res < 0)
6387 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006388 Py_INCREF(Py_None);
6389 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006390}
6391
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006392
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006393PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006394"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006395Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006396
Barry Warsaw53699e91996-12-10 23:23:01 +00006397static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006398posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006399{
6400 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006401#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006402 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006403#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006404 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006405#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006406 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006407 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006408 return NULL;
6409#ifdef SEEK_SET
6410 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6411 switch (how) {
6412 case 0: how = SEEK_SET; break;
6413 case 1: how = SEEK_CUR; break;
6414 case 2: how = SEEK_END; break;
6415 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006416#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006417
6418#if !defined(HAVE_LARGEFILE_SUPPORT)
6419 pos = PyInt_AsLong(posobj);
6420#else
6421 pos = PyLong_Check(posobj) ?
6422 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6423#endif
6424 if (PyErr_Occurred())
6425 return NULL;
6426
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006427 if (!_PyVerify_fd(fd))
6428 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006429 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006430#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006431 res = _lseeki64(fd, pos, how);
6432#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006433 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006434#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006435 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006436 if (res < 0)
6437 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006438
6439#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006440 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006441#else
6442 return PyLong_FromLongLong(res);
6443#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006444}
6445
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006446
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006447PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006448"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006449Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006450
Barry Warsaw53699e91996-12-10 23:23:01 +00006451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006452posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006453{
Guido van Rossum8bac5461996-06-11 18:38:48 +00006454 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006455 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006456 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006457 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006458 if (size < 0) {
6459 errno = EINVAL;
6460 return posix_error();
6461 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006462 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006463 if (buffer == NULL)
6464 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006465 if (!_PyVerify_fd(fd))
6466 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006467 Py_BEGIN_ALLOW_THREADS
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006468 n = read(fd, PyString_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006469 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006470 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006471 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006472 return posix_error();
6473 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006474 if (n != size)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006475 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006476 return buffer;
6477}
6478
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006479
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006480PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006481"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006482Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006483
Barry Warsaw53699e91996-12-10 23:23:01 +00006484static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006485posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006486{
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006487 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006488 int fd;
6489 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006490
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006491 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00006492 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006493 if (!_PyVerify_fd(fd))
6494 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006495 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006496 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00006497 Py_END_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006498 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00006499 if (size < 0)
6500 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006501 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006502}
6503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006504
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006505PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006506"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006507Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006508
Barry Warsaw53699e91996-12-10 23:23:01 +00006509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006510posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006511{
6512 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006513 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006514 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006515 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006516 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006517#ifdef __VMS
6518 /* on OpenVMS we must ensure that all bytes are written to the file */
6519 fsync(fd);
6520#endif
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006521 if (!_PyVerify_fd(fd))
6522 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006523 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006524 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006525 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006526 if (res != 0) {
6527#ifdef MS_WINDOWS
6528 return win32_error("fstat", NULL);
6529#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006530 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006531#endif
6532 }
Tim Peters5aa91602002-01-30 05:46:57 +00006533
Martin v. Löwis14694662006-02-03 12:54:16 +00006534 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006535}
6536
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006537
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006538PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006539"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006540Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006541
Barry Warsaw53699e91996-12-10 23:23:01 +00006542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006543posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006544{
Guido van Rossum687dd131993-05-17 08:34:16 +00006545 int fd;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006546 char *orgmode = "r";
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006547 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006548 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006549 PyObject *f;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006550 char *mode;
6551 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006552 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006553
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006554 /* Sanitize mode. See fileobject.c */
6555 mode = PyMem_MALLOC(strlen(orgmode)+3);
6556 if (!mode) {
6557 PyErr_NoMemory();
6558 return NULL;
6559 }
6560 strcpy(mode, orgmode);
6561 if (_PyFile_SanitizeMode(mode)) {
6562 PyMem_FREE(mode);
Thomas Heller1f043e22002-11-07 16:00:59 +00006563 return NULL;
6564 }
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006565 if (!_PyVerify_fd(fd))
6566 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006567 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006568#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006569 if (mode[0] == 'a') {
6570 /* try to make sure the O_APPEND flag is set */
6571 int flags;
6572 flags = fcntl(fd, F_GETFL);
6573 if (flags != -1)
6574 fcntl(fd, F_SETFL, flags | O_APPEND);
6575 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006576 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006577 /* restore old mode if fdopen failed */
6578 fcntl(fd, F_SETFL, flags);
6579 } else {
6580 fp = fdopen(fd, mode);
6581 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006582#else
6583 fp = fdopen(fd, mode);
6584#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006585 Py_END_ALLOW_THREADS
Neal Norwitzd83eb312007-05-02 04:47:55 +00006586 PyMem_FREE(mode);
Guido van Rossum687dd131993-05-17 08:34:16 +00006587 if (fp == NULL)
6588 return posix_error();
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006589 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006590 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006591 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006592 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006593}
6594
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006595PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006596"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006597Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006598connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006599
6600static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006601posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006602{
6603 int fd;
6604 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6605 return NULL;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +00006606 if (!_PyVerify_fd(fd))
6607 return PyBool_FromLong(0);
Fred Drake106c1a02002-04-23 15:58:02 +00006608 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006609}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006610
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006611#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006612PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006613"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006614Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006615
Barry Warsaw53699e91996-12-10 23:23:01 +00006616static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006617posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006618{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006619#if defined(PYOS_OS2)
6620 HFILE read, write;
6621 APIRET rc;
6622
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006623 Py_BEGIN_ALLOW_THREADS
6624 rc = DosCreatePipe( &read, &write, 4096);
6625 Py_END_ALLOW_THREADS
6626 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006627 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006628
6629 return Py_BuildValue("(ii)", read, write);
6630#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006631#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006632 int fds[2];
6633 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006634 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006635 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006636 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006637 if (res != 0)
6638 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006639 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006640#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006641 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006642 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006643 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006644 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006645 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006646 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006647 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006648 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006649 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6650 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006651 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006652#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006653#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006654}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006655#endif /* HAVE_PIPE */
6656
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006657
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006658#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006659PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006660"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006661Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006662
Barry Warsaw53699e91996-12-10 23:23:01 +00006663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006664posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006665{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006666 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006667 int mode = 0666;
6668 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006669 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006670 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006671 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006672 res = mkfifo(filename, mode);
6673 Py_END_ALLOW_THREADS
6674 if (res < 0)
6675 return posix_error();
6676 Py_INCREF(Py_None);
6677 return Py_None;
6678}
6679#endif
6680
6681
Neal Norwitz11690112002-07-30 01:08:28 +00006682#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006683PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006684"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006685Create a filesystem node (file, device special file or named pipe)\n\
6686named filename. mode specifies both the permissions to use and the\n\
6687type of node to be created, being combined (bitwise OR) with one of\n\
6688S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006689device defines the newly created device special file (probably using\n\
6690os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006691
6692
6693static PyObject *
6694posix_mknod(PyObject *self, PyObject *args)
6695{
6696 char *filename;
6697 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006698 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006699 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006700 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006701 return NULL;
6702 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006703 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006704 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006705 if (res < 0)
6706 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006707 Py_INCREF(Py_None);
6708 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006709}
6710#endif
6711
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006712#ifdef HAVE_DEVICE_MACROS
6713PyDoc_STRVAR(posix_major__doc__,
6714"major(device) -> major number\n\
6715Extracts a device major number from a raw device number.");
6716
6717static PyObject *
6718posix_major(PyObject *self, PyObject *args)
6719{
6720 int device;
6721 if (!PyArg_ParseTuple(args, "i:major", &device))
6722 return NULL;
6723 return PyInt_FromLong((long)major(device));
6724}
6725
6726PyDoc_STRVAR(posix_minor__doc__,
6727"minor(device) -> minor number\n\
6728Extracts a device minor number from a raw device number.");
6729
6730static PyObject *
6731posix_minor(PyObject *self, PyObject *args)
6732{
6733 int device;
6734 if (!PyArg_ParseTuple(args, "i:minor", &device))
6735 return NULL;
6736 return PyInt_FromLong((long)minor(device));
6737}
6738
6739PyDoc_STRVAR(posix_makedev__doc__,
6740"makedev(major, minor) -> device number\n\
6741Composes a raw device number from the major and minor device numbers.");
6742
6743static PyObject *
6744posix_makedev(PyObject *self, PyObject *args)
6745{
6746 int major, minor;
6747 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6748 return NULL;
6749 return PyInt_FromLong((long)makedev(major, minor));
6750}
6751#endif /* device macros */
6752
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006753
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006754#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006755PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006756"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006757Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006758
Barry Warsaw53699e91996-12-10 23:23:01 +00006759static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006760posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006761{
6762 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006763 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006764 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006765 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006766
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006767 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006768 return NULL;
6769
6770#if !defined(HAVE_LARGEFILE_SUPPORT)
6771 length = PyInt_AsLong(lenobj);
6772#else
6773 length = PyLong_Check(lenobj) ?
6774 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6775#endif
6776 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006777 return NULL;
6778
Barry Warsaw53699e91996-12-10 23:23:01 +00006779 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006780 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006781 Py_END_ALLOW_THREADS
Benjamin Peterson943a6dd2009-01-19 15:51:27 +00006782 if (res < 0)
6783 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006784 Py_INCREF(Py_None);
6785 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006786}
6787#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006788
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006789#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006790PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006791"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006792Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006793
Fred Drake762e2061999-08-26 17:23:54 +00006794/* Save putenv() parameters as values here, so we can collect them when they
6795 * get re-set with another call for the same key. */
6796static PyObject *posix_putenv_garbage;
6797
Tim Peters5aa91602002-01-30 05:46:57 +00006798static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006799posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006800{
6801 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006802 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006803 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006804 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006805
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006806 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006807 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006808
6809#if defined(PYOS_OS2)
6810 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6811 APIRET rc;
6812
Guido van Rossumd48f2521997-12-05 22:19:34 +00006813 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6814 if (rc != NO_ERROR)
6815 return os2_error(rc);
6816
6817 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6818 APIRET rc;
6819
Guido van Rossumd48f2521997-12-05 22:19:34 +00006820 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6821 if (rc != NO_ERROR)
6822 return os2_error(rc);
6823 } else {
6824#endif
6825
Fred Drake762e2061999-08-26 17:23:54 +00006826 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006827 len = strlen(s1) + strlen(s2) + 2;
6828 /* len includes space for a trailing \0; the size arg to
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006829 PyString_FromStringAndSize does not count that */
6830 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006831 if (newstr == NULL)
6832 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006833 newenv = PyString_AS_STRING(newstr);
Anthony Baxter64182fe2006-04-11 12:14:09 +00006834 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6835 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006836 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006837 posix_error();
6838 return NULL;
6839 }
Fred Drake762e2061999-08-26 17:23:54 +00006840 /* Install the first arg and newstr in posix_putenv_garbage;
6841 * this will cause previous value to be collected. This has to
6842 * happen after the real putenv() call because the old value
6843 * was still accessible until then. */
6844 if (PyDict_SetItem(posix_putenv_garbage,
6845 PyTuple_GET_ITEM(args, 0), newstr)) {
6846 /* really not much we can do; just leak */
6847 PyErr_Clear();
6848 }
6849 else {
6850 Py_DECREF(newstr);
6851 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006852
6853#if defined(PYOS_OS2)
6854 }
6855#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006856 Py_INCREF(Py_None);
6857 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006858}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006859#endif /* putenv */
6860
Guido van Rossumc524d952001-10-19 01:31:59 +00006861#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006862PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006863"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006864Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006865
6866static PyObject *
6867posix_unsetenv(PyObject *self, PyObject *args)
6868{
6869 char *s1;
6870
6871 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6872 return NULL;
6873
6874 unsetenv(s1);
6875
6876 /* Remove the key from posix_putenv_garbage;
6877 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006878 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006879 * old value was still accessible until then.
6880 */
6881 if (PyDict_DelItem(posix_putenv_garbage,
6882 PyTuple_GET_ITEM(args, 0))) {
6883 /* really not much we can do; just leak */
6884 PyErr_Clear();
6885 }
6886
6887 Py_INCREF(Py_None);
6888 return Py_None;
6889}
6890#endif /* unsetenv */
6891
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006892PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006893"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006894Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006895
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006896static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006897posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006898{
6899 int code;
6900 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006901 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006902 return NULL;
6903 message = strerror(code);
6904 if (message == NULL) {
6905 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006906 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006907 return NULL;
6908 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006909 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006910}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006911
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006912
Guido van Rossumc9641791998-08-04 15:26:23 +00006913#ifdef HAVE_SYS_WAIT_H
6914
Fred Drake106c1a02002-04-23 15:58:02 +00006915#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006916PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006917"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006918Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006919
6920static PyObject *
6921posix_WCOREDUMP(PyObject *self, PyObject *args)
6922{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006923 WAIT_TYPE status;
6924 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006925
Neal Norwitzd5a37542006-03-20 06:48:34 +00006926 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006927 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006928
6929 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006930}
6931#endif /* WCOREDUMP */
6932
6933#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006934PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006935"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006936Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006937job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006938
6939static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006940posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006941{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006942 WAIT_TYPE status;
6943 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006944
Neal Norwitzd5a37542006-03-20 06:48:34 +00006945 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006946 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006947
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006948 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006949}
6950#endif /* WIFCONTINUED */
6951
Guido van Rossumc9641791998-08-04 15:26:23 +00006952#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006953PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006954"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006955Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006956
6957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006958posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006959{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006960 WAIT_TYPE status;
6961 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006962
Neal Norwitzd5a37542006-03-20 06:48:34 +00006963 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006964 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006965
Fred Drake106c1a02002-04-23 15:58:02 +00006966 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006967}
6968#endif /* WIFSTOPPED */
6969
6970#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006971PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006972"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006973Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006974
6975static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006976posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006977{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006978 WAIT_TYPE status;
6979 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006980
Neal Norwitzd5a37542006-03-20 06:48:34 +00006981 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006982 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006983
Fred Drake106c1a02002-04-23 15:58:02 +00006984 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006985}
6986#endif /* WIFSIGNALED */
6987
6988#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006989PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006990"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006991Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006992system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006993
6994static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006995posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006996{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006997 WAIT_TYPE status;
6998 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006999
Neal Norwitzd5a37542006-03-20 06:48:34 +00007000 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007001 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007002
Fred Drake106c1a02002-04-23 15:58:02 +00007003 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007004}
7005#endif /* WIFEXITED */
7006
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007007#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007008PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007009"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007010Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007011
7012static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007013posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007014{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007015 WAIT_TYPE status;
7016 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007017
Neal Norwitzd5a37542006-03-20 06:48:34 +00007018 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007019 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007020
Guido van Rossumc9641791998-08-04 15:26:23 +00007021 return Py_BuildValue("i", WEXITSTATUS(status));
7022}
7023#endif /* WEXITSTATUS */
7024
7025#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007026PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007027"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007028Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007029value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007030
7031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007032posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007033{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007034 WAIT_TYPE status;
7035 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007036
Neal Norwitzd5a37542006-03-20 06:48:34 +00007037 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007038 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007039
Guido van Rossumc9641791998-08-04 15:26:23 +00007040 return Py_BuildValue("i", WTERMSIG(status));
7041}
7042#endif /* WTERMSIG */
7043
7044#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007045PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007046"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007047Return the signal that stopped the process that provided\n\
7048the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007049
7050static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007051posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007052{
Neal Norwitzd5a37542006-03-20 06:48:34 +00007053 WAIT_TYPE status;
7054 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007055
Neal Norwitzd5a37542006-03-20 06:48:34 +00007056 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00007057 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007058
Guido van Rossumc9641791998-08-04 15:26:23 +00007059 return Py_BuildValue("i", WSTOPSIG(status));
7060}
7061#endif /* WSTOPSIG */
7062
7063#endif /* HAVE_SYS_WAIT_H */
7064
7065
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007066#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007067#ifdef _SCO_DS
7068/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7069 needed definitions in sys/statvfs.h */
7070#define _SVID3
7071#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007072#include <sys/statvfs.h>
7073
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007074static PyObject*
7075_pystatvfs_fromstructstatvfs(struct statvfs st) {
7076 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7077 if (v == NULL)
7078 return NULL;
7079
7080#if !defined(HAVE_LARGEFILE_SUPPORT)
7081 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7082 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7083 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7084 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7085 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7086 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7087 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7088 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7089 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7090 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7091#else
7092 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7093 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00007094 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007095 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00007096 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007097 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007098 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007099 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00007100 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007101 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00007102 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007103 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00007104 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007105 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007106 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7107 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7108#endif
7109
7110 return v;
7111}
7112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007113PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007114"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007115Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007116
7117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007118posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007119{
7120 int fd, res;
7121 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007122
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007123 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007124 return NULL;
7125 Py_BEGIN_ALLOW_THREADS
7126 res = fstatvfs(fd, &st);
7127 Py_END_ALLOW_THREADS
7128 if (res != 0)
7129 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007130
7131 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007132}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007133#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007134
7135
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007136#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007137#include <sys/statvfs.h>
7138
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007139PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007140"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007141Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007142
7143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007144posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007145{
7146 char *path;
7147 int res;
7148 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007149 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007150 return NULL;
7151 Py_BEGIN_ALLOW_THREADS
7152 res = statvfs(path, &st);
7153 Py_END_ALLOW_THREADS
7154 if (res != 0)
7155 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007156
7157 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007158}
7159#endif /* HAVE_STATVFS */
7160
7161
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007162#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007163PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007164"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007165Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007166The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007167or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007168
7169static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007170posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007171{
7172 PyObject *result = NULL;
7173 char *dir = NULL;
7174 char *pfx = NULL;
7175 char *name;
7176
7177 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7178 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007179
7180 if (PyErr_Warn(PyExc_RuntimeWarning,
7181 "tempnam is a potential security risk to your program") < 0)
7182 return NULL;
7183
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007184#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007185 name = _tempnam(dir, pfx);
7186#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007187 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007188#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007189 if (name == NULL)
7190 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007191 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007192 free(name);
7193 return result;
7194}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007195#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007196
7197
7198#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007199PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007200"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007201Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007202
7203static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007204posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007205{
7206 FILE *fp;
7207
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007208 fp = tmpfile();
7209 if (fp == NULL)
7210 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007211 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007212}
7213#endif
7214
7215
7216#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007217PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007218"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007219Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007220
7221static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007222posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007223{
7224 char buffer[L_tmpnam];
7225 char *name;
7226
Skip Montanaro95618b52001-08-18 18:52:10 +00007227 if (PyErr_Warn(PyExc_RuntimeWarning,
7228 "tmpnam is a potential security risk to your program") < 0)
7229 return NULL;
7230
Greg Wardb48bc172000-03-01 21:51:56 +00007231#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007232 name = tmpnam_r(buffer);
7233#else
7234 name = tmpnam(buffer);
7235#endif
7236 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007237 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007238#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007239 "unexpected NULL from tmpnam_r"
7240#else
7241 "unexpected NULL from tmpnam"
7242#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007243 );
7244 PyErr_SetObject(PyExc_OSError, err);
7245 Py_XDECREF(err);
7246 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007247 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007248 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007249}
7250#endif
7251
7252
Fred Drakec9680921999-12-13 16:37:25 +00007253/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7254 * It maps strings representing configuration variable names to
7255 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007256 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007257 * rarely-used constants. There are three separate tables that use
7258 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007259 *
7260 * This code is always included, even if none of the interfaces that
7261 * need it are included. The #if hackery needed to avoid it would be
7262 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007263 */
7264struct constdef {
7265 char *name;
7266 long value;
7267};
7268
Fred Drake12c6e2d1999-12-14 21:25:03 +00007269static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007270conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7271 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007272{
7273 if (PyInt_Check(arg)) {
7274 *valuep = PyInt_AS_LONG(arg);
7275 return 1;
7276 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007277 if (PyString_Check(arg)) {
Fred Drake12c6e2d1999-12-14 21:25:03 +00007278 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00007279 size_t lo = 0;
7280 size_t mid;
7281 size_t hi = tablesize;
7282 int cmp;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007283 char *confname = PyString_AS_STRING(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007284 while (lo < hi) {
7285 mid = (lo + hi) / 2;
7286 cmp = strcmp(confname, table[mid].name);
7287 if (cmp < 0)
7288 hi = mid;
7289 else if (cmp > 0)
7290 lo = mid + 1;
7291 else {
7292 *valuep = table[mid].value;
7293 return 1;
7294 }
7295 }
7296 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7297 }
7298 else
7299 PyErr_SetString(PyExc_TypeError,
7300 "configuration names must be strings or integers");
7301 return 0;
7302}
7303
7304
7305#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7306static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007307#ifdef _PC_ABI_AIO_XFER_MAX
7308 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7309#endif
7310#ifdef _PC_ABI_ASYNC_IO
7311 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7312#endif
Fred Drakec9680921999-12-13 16:37:25 +00007313#ifdef _PC_ASYNC_IO
7314 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7315#endif
7316#ifdef _PC_CHOWN_RESTRICTED
7317 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7318#endif
7319#ifdef _PC_FILESIZEBITS
7320 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7321#endif
7322#ifdef _PC_LAST
7323 {"PC_LAST", _PC_LAST},
7324#endif
7325#ifdef _PC_LINK_MAX
7326 {"PC_LINK_MAX", _PC_LINK_MAX},
7327#endif
7328#ifdef _PC_MAX_CANON
7329 {"PC_MAX_CANON", _PC_MAX_CANON},
7330#endif
7331#ifdef _PC_MAX_INPUT
7332 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7333#endif
7334#ifdef _PC_NAME_MAX
7335 {"PC_NAME_MAX", _PC_NAME_MAX},
7336#endif
7337#ifdef _PC_NO_TRUNC
7338 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7339#endif
7340#ifdef _PC_PATH_MAX
7341 {"PC_PATH_MAX", _PC_PATH_MAX},
7342#endif
7343#ifdef _PC_PIPE_BUF
7344 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7345#endif
7346#ifdef _PC_PRIO_IO
7347 {"PC_PRIO_IO", _PC_PRIO_IO},
7348#endif
7349#ifdef _PC_SOCK_MAXBUF
7350 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7351#endif
7352#ifdef _PC_SYNC_IO
7353 {"PC_SYNC_IO", _PC_SYNC_IO},
7354#endif
7355#ifdef _PC_VDISABLE
7356 {"PC_VDISABLE", _PC_VDISABLE},
7357#endif
7358};
7359
Fred Drakec9680921999-12-13 16:37:25 +00007360static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007361conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007362{
7363 return conv_confname(arg, valuep, posix_constants_pathconf,
7364 sizeof(posix_constants_pathconf)
7365 / sizeof(struct constdef));
7366}
7367#endif
7368
7369#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007370PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007371"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007372Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007373If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007374
7375static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007376posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007377{
7378 PyObject *result = NULL;
7379 int name, fd;
7380
Fred Drake12c6e2d1999-12-14 21:25:03 +00007381 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7382 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00007383 long limit;
7384
7385 errno = 0;
7386 limit = fpathconf(fd, name);
7387 if (limit == -1 && errno != 0)
7388 posix_error();
7389 else
7390 result = PyInt_FromLong(limit);
7391 }
7392 return result;
7393}
7394#endif
7395
7396
7397#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007398PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007399"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007400Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007401If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007402
7403static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007404posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007405{
7406 PyObject *result = NULL;
7407 int name;
7408 char *path;
7409
7410 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7411 conv_path_confname, &name)) {
7412 long limit;
7413
7414 errno = 0;
7415 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007416 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00007417 if (errno == EINVAL)
7418 /* could be a path or name problem */
7419 posix_error();
7420 else
7421 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007422 }
Fred Drakec9680921999-12-13 16:37:25 +00007423 else
7424 result = PyInt_FromLong(limit);
7425 }
7426 return result;
7427}
7428#endif
7429
7430#ifdef HAVE_CONFSTR
7431static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007432#ifdef _CS_ARCHITECTURE
7433 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7434#endif
7435#ifdef _CS_HOSTNAME
7436 {"CS_HOSTNAME", _CS_HOSTNAME},
7437#endif
7438#ifdef _CS_HW_PROVIDER
7439 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7440#endif
7441#ifdef _CS_HW_SERIAL
7442 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7443#endif
7444#ifdef _CS_INITTAB_NAME
7445 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7446#endif
Fred Drakec9680921999-12-13 16:37:25 +00007447#ifdef _CS_LFS64_CFLAGS
7448 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7449#endif
7450#ifdef _CS_LFS64_LDFLAGS
7451 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7452#endif
7453#ifdef _CS_LFS64_LIBS
7454 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7455#endif
7456#ifdef _CS_LFS64_LINTFLAGS
7457 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7458#endif
7459#ifdef _CS_LFS_CFLAGS
7460 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7461#endif
7462#ifdef _CS_LFS_LDFLAGS
7463 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7464#endif
7465#ifdef _CS_LFS_LIBS
7466 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7467#endif
7468#ifdef _CS_LFS_LINTFLAGS
7469 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7470#endif
Fred Draked86ed291999-12-15 15:34:33 +00007471#ifdef _CS_MACHINE
7472 {"CS_MACHINE", _CS_MACHINE},
7473#endif
Fred Drakec9680921999-12-13 16:37:25 +00007474#ifdef _CS_PATH
7475 {"CS_PATH", _CS_PATH},
7476#endif
Fred Draked86ed291999-12-15 15:34:33 +00007477#ifdef _CS_RELEASE
7478 {"CS_RELEASE", _CS_RELEASE},
7479#endif
7480#ifdef _CS_SRPC_DOMAIN
7481 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7482#endif
7483#ifdef _CS_SYSNAME
7484 {"CS_SYSNAME", _CS_SYSNAME},
7485#endif
7486#ifdef _CS_VERSION
7487 {"CS_VERSION", _CS_VERSION},
7488#endif
Fred Drakec9680921999-12-13 16:37:25 +00007489#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7490 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7491#endif
7492#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7493 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7494#endif
7495#ifdef _CS_XBS5_ILP32_OFF32_LIBS
7496 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7497#endif
7498#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7499 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7500#endif
7501#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7502 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7503#endif
7504#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7505 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7506#endif
7507#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7508 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7509#endif
7510#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7511 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7512#endif
7513#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7514 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7515#endif
7516#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7517 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7518#endif
7519#ifdef _CS_XBS5_LP64_OFF64_LIBS
7520 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7521#endif
7522#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7523 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7524#endif
7525#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7526 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7527#endif
7528#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7529 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7530#endif
7531#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7532 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7533#endif
7534#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7535 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7536#endif
Fred Draked86ed291999-12-15 15:34:33 +00007537#ifdef _MIPS_CS_AVAIL_PROCESSORS
7538 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7539#endif
7540#ifdef _MIPS_CS_BASE
7541 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7542#endif
7543#ifdef _MIPS_CS_HOSTID
7544 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7545#endif
7546#ifdef _MIPS_CS_HW_NAME
7547 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7548#endif
7549#ifdef _MIPS_CS_NUM_PROCESSORS
7550 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7551#endif
7552#ifdef _MIPS_CS_OSREL_MAJ
7553 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7554#endif
7555#ifdef _MIPS_CS_OSREL_MIN
7556 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7557#endif
7558#ifdef _MIPS_CS_OSREL_PATCH
7559 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7560#endif
7561#ifdef _MIPS_CS_OS_NAME
7562 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7563#endif
7564#ifdef _MIPS_CS_OS_PROVIDER
7565 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7566#endif
7567#ifdef _MIPS_CS_PROCESSORS
7568 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7569#endif
7570#ifdef _MIPS_CS_SERIAL
7571 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7572#endif
7573#ifdef _MIPS_CS_VENDOR
7574 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7575#endif
Fred Drakec9680921999-12-13 16:37:25 +00007576};
7577
7578static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007579conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007580{
7581 return conv_confname(arg, valuep, posix_constants_confstr,
7582 sizeof(posix_constants_confstr)
7583 / sizeof(struct constdef));
7584}
7585
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007586PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007587"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007588Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007589
7590static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007591posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007592{
7593 PyObject *result = NULL;
7594 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007595 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007596
7597 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007598 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007599
Fred Drakec9680921999-12-13 16:37:25 +00007600 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007601 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007602 if (len == 0) {
7603 if (errno) {
7604 posix_error();
7605 }
7606 else {
7607 result = Py_None;
7608 Py_INCREF(Py_None);
7609 }
Fred Drakec9680921999-12-13 16:37:25 +00007610 }
7611 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007612 if ((unsigned int)len >= sizeof(buffer)) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007613 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007614 if (result != NULL)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007615 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007616 }
7617 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007618 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007619 }
7620 }
7621 return result;
7622}
7623#endif
7624
7625
7626#ifdef HAVE_SYSCONF
7627static struct constdef posix_constants_sysconf[] = {
7628#ifdef _SC_2_CHAR_TERM
7629 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7630#endif
7631#ifdef _SC_2_C_BIND
7632 {"SC_2_C_BIND", _SC_2_C_BIND},
7633#endif
7634#ifdef _SC_2_C_DEV
7635 {"SC_2_C_DEV", _SC_2_C_DEV},
7636#endif
7637#ifdef _SC_2_C_VERSION
7638 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7639#endif
7640#ifdef _SC_2_FORT_DEV
7641 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7642#endif
7643#ifdef _SC_2_FORT_RUN
7644 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7645#endif
7646#ifdef _SC_2_LOCALEDEF
7647 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7648#endif
7649#ifdef _SC_2_SW_DEV
7650 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7651#endif
7652#ifdef _SC_2_UPE
7653 {"SC_2_UPE", _SC_2_UPE},
7654#endif
7655#ifdef _SC_2_VERSION
7656 {"SC_2_VERSION", _SC_2_VERSION},
7657#endif
Fred Draked86ed291999-12-15 15:34:33 +00007658#ifdef _SC_ABI_ASYNCHRONOUS_IO
7659 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7660#endif
7661#ifdef _SC_ACL
7662 {"SC_ACL", _SC_ACL},
7663#endif
Fred Drakec9680921999-12-13 16:37:25 +00007664#ifdef _SC_AIO_LISTIO_MAX
7665 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7666#endif
Fred Drakec9680921999-12-13 16:37:25 +00007667#ifdef _SC_AIO_MAX
7668 {"SC_AIO_MAX", _SC_AIO_MAX},
7669#endif
7670#ifdef _SC_AIO_PRIO_DELTA_MAX
7671 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7672#endif
7673#ifdef _SC_ARG_MAX
7674 {"SC_ARG_MAX", _SC_ARG_MAX},
7675#endif
7676#ifdef _SC_ASYNCHRONOUS_IO
7677 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7678#endif
7679#ifdef _SC_ATEXIT_MAX
7680 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7681#endif
Fred Draked86ed291999-12-15 15:34:33 +00007682#ifdef _SC_AUDIT
7683 {"SC_AUDIT", _SC_AUDIT},
7684#endif
Fred Drakec9680921999-12-13 16:37:25 +00007685#ifdef _SC_AVPHYS_PAGES
7686 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7687#endif
7688#ifdef _SC_BC_BASE_MAX
7689 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7690#endif
7691#ifdef _SC_BC_DIM_MAX
7692 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7693#endif
7694#ifdef _SC_BC_SCALE_MAX
7695 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7696#endif
7697#ifdef _SC_BC_STRING_MAX
7698 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7699#endif
Fred Draked86ed291999-12-15 15:34:33 +00007700#ifdef _SC_CAP
7701 {"SC_CAP", _SC_CAP},
7702#endif
Fred Drakec9680921999-12-13 16:37:25 +00007703#ifdef _SC_CHARCLASS_NAME_MAX
7704 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7705#endif
7706#ifdef _SC_CHAR_BIT
7707 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7708#endif
7709#ifdef _SC_CHAR_MAX
7710 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7711#endif
7712#ifdef _SC_CHAR_MIN
7713 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7714#endif
7715#ifdef _SC_CHILD_MAX
7716 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7717#endif
7718#ifdef _SC_CLK_TCK
7719 {"SC_CLK_TCK", _SC_CLK_TCK},
7720#endif
7721#ifdef _SC_COHER_BLKSZ
7722 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7723#endif
7724#ifdef _SC_COLL_WEIGHTS_MAX
7725 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7726#endif
7727#ifdef _SC_DCACHE_ASSOC
7728 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7729#endif
7730#ifdef _SC_DCACHE_BLKSZ
7731 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7732#endif
7733#ifdef _SC_DCACHE_LINESZ
7734 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7735#endif
7736#ifdef _SC_DCACHE_SZ
7737 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7738#endif
7739#ifdef _SC_DCACHE_TBLKSZ
7740 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7741#endif
7742#ifdef _SC_DELAYTIMER_MAX
7743 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7744#endif
7745#ifdef _SC_EQUIV_CLASS_MAX
7746 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7747#endif
7748#ifdef _SC_EXPR_NEST_MAX
7749 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7750#endif
7751#ifdef _SC_FSYNC
7752 {"SC_FSYNC", _SC_FSYNC},
7753#endif
7754#ifdef _SC_GETGR_R_SIZE_MAX
7755 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7756#endif
7757#ifdef _SC_GETPW_R_SIZE_MAX
7758 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7759#endif
7760#ifdef _SC_ICACHE_ASSOC
7761 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7762#endif
7763#ifdef _SC_ICACHE_BLKSZ
7764 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7765#endif
7766#ifdef _SC_ICACHE_LINESZ
7767 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7768#endif
7769#ifdef _SC_ICACHE_SZ
7770 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7771#endif
Fred Draked86ed291999-12-15 15:34:33 +00007772#ifdef _SC_INF
7773 {"SC_INF", _SC_INF},
7774#endif
Fred Drakec9680921999-12-13 16:37:25 +00007775#ifdef _SC_INT_MAX
7776 {"SC_INT_MAX", _SC_INT_MAX},
7777#endif
7778#ifdef _SC_INT_MIN
7779 {"SC_INT_MIN", _SC_INT_MIN},
7780#endif
7781#ifdef _SC_IOV_MAX
7782 {"SC_IOV_MAX", _SC_IOV_MAX},
7783#endif
Fred Draked86ed291999-12-15 15:34:33 +00007784#ifdef _SC_IP_SECOPTS
7785 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7786#endif
Fred Drakec9680921999-12-13 16:37:25 +00007787#ifdef _SC_JOB_CONTROL
7788 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7789#endif
Fred Draked86ed291999-12-15 15:34:33 +00007790#ifdef _SC_KERN_POINTERS
7791 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7792#endif
7793#ifdef _SC_KERN_SIM
7794 {"SC_KERN_SIM", _SC_KERN_SIM},
7795#endif
Fred Drakec9680921999-12-13 16:37:25 +00007796#ifdef _SC_LINE_MAX
7797 {"SC_LINE_MAX", _SC_LINE_MAX},
7798#endif
7799#ifdef _SC_LOGIN_NAME_MAX
7800 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7801#endif
7802#ifdef _SC_LOGNAME_MAX
7803 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7804#endif
7805#ifdef _SC_LONG_BIT
7806 {"SC_LONG_BIT", _SC_LONG_BIT},
7807#endif
Fred Draked86ed291999-12-15 15:34:33 +00007808#ifdef _SC_MAC
7809 {"SC_MAC", _SC_MAC},
7810#endif
Fred Drakec9680921999-12-13 16:37:25 +00007811#ifdef _SC_MAPPED_FILES
7812 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7813#endif
7814#ifdef _SC_MAXPID
7815 {"SC_MAXPID", _SC_MAXPID},
7816#endif
7817#ifdef _SC_MB_LEN_MAX
7818 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7819#endif
7820#ifdef _SC_MEMLOCK
7821 {"SC_MEMLOCK", _SC_MEMLOCK},
7822#endif
7823#ifdef _SC_MEMLOCK_RANGE
7824 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7825#endif
7826#ifdef _SC_MEMORY_PROTECTION
7827 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7828#endif
7829#ifdef _SC_MESSAGE_PASSING
7830 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7831#endif
Fred Draked86ed291999-12-15 15:34:33 +00007832#ifdef _SC_MMAP_FIXED_ALIGNMENT
7833 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7834#endif
Fred Drakec9680921999-12-13 16:37:25 +00007835#ifdef _SC_MQ_OPEN_MAX
7836 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7837#endif
7838#ifdef _SC_MQ_PRIO_MAX
7839 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7840#endif
Fred Draked86ed291999-12-15 15:34:33 +00007841#ifdef _SC_NACLS_MAX
7842 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7843#endif
Fred Drakec9680921999-12-13 16:37:25 +00007844#ifdef _SC_NGROUPS_MAX
7845 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7846#endif
7847#ifdef _SC_NL_ARGMAX
7848 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7849#endif
7850#ifdef _SC_NL_LANGMAX
7851 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7852#endif
7853#ifdef _SC_NL_MSGMAX
7854 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7855#endif
7856#ifdef _SC_NL_NMAX
7857 {"SC_NL_NMAX", _SC_NL_NMAX},
7858#endif
7859#ifdef _SC_NL_SETMAX
7860 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7861#endif
7862#ifdef _SC_NL_TEXTMAX
7863 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7864#endif
7865#ifdef _SC_NPROCESSORS_CONF
7866 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7867#endif
7868#ifdef _SC_NPROCESSORS_ONLN
7869 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7870#endif
Fred Draked86ed291999-12-15 15:34:33 +00007871#ifdef _SC_NPROC_CONF
7872 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7873#endif
7874#ifdef _SC_NPROC_ONLN
7875 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7876#endif
Fred Drakec9680921999-12-13 16:37:25 +00007877#ifdef _SC_NZERO
7878 {"SC_NZERO", _SC_NZERO},
7879#endif
7880#ifdef _SC_OPEN_MAX
7881 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7882#endif
7883#ifdef _SC_PAGESIZE
7884 {"SC_PAGESIZE", _SC_PAGESIZE},
7885#endif
7886#ifdef _SC_PAGE_SIZE
7887 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7888#endif
7889#ifdef _SC_PASS_MAX
7890 {"SC_PASS_MAX", _SC_PASS_MAX},
7891#endif
7892#ifdef _SC_PHYS_PAGES
7893 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7894#endif
7895#ifdef _SC_PII
7896 {"SC_PII", _SC_PII},
7897#endif
7898#ifdef _SC_PII_INTERNET
7899 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7900#endif
7901#ifdef _SC_PII_INTERNET_DGRAM
7902 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7903#endif
7904#ifdef _SC_PII_INTERNET_STREAM
7905 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7906#endif
7907#ifdef _SC_PII_OSI
7908 {"SC_PII_OSI", _SC_PII_OSI},
7909#endif
7910#ifdef _SC_PII_OSI_CLTS
7911 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7912#endif
7913#ifdef _SC_PII_OSI_COTS
7914 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7915#endif
7916#ifdef _SC_PII_OSI_M
7917 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7918#endif
7919#ifdef _SC_PII_SOCKET
7920 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7921#endif
7922#ifdef _SC_PII_XTI
7923 {"SC_PII_XTI", _SC_PII_XTI},
7924#endif
7925#ifdef _SC_POLL
7926 {"SC_POLL", _SC_POLL},
7927#endif
7928#ifdef _SC_PRIORITIZED_IO
7929 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7930#endif
7931#ifdef _SC_PRIORITY_SCHEDULING
7932 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7933#endif
7934#ifdef _SC_REALTIME_SIGNALS
7935 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7936#endif
7937#ifdef _SC_RE_DUP_MAX
7938 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7939#endif
7940#ifdef _SC_RTSIG_MAX
7941 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7942#endif
7943#ifdef _SC_SAVED_IDS
7944 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7945#endif
7946#ifdef _SC_SCHAR_MAX
7947 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7948#endif
7949#ifdef _SC_SCHAR_MIN
7950 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7951#endif
7952#ifdef _SC_SELECT
7953 {"SC_SELECT", _SC_SELECT},
7954#endif
7955#ifdef _SC_SEMAPHORES
7956 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7957#endif
7958#ifdef _SC_SEM_NSEMS_MAX
7959 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7960#endif
7961#ifdef _SC_SEM_VALUE_MAX
7962 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7963#endif
7964#ifdef _SC_SHARED_MEMORY_OBJECTS
7965 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7966#endif
7967#ifdef _SC_SHRT_MAX
7968 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7969#endif
7970#ifdef _SC_SHRT_MIN
7971 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7972#endif
7973#ifdef _SC_SIGQUEUE_MAX
7974 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7975#endif
7976#ifdef _SC_SIGRT_MAX
7977 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7978#endif
7979#ifdef _SC_SIGRT_MIN
7980 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7981#endif
Fred Draked86ed291999-12-15 15:34:33 +00007982#ifdef _SC_SOFTPOWER
7983 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7984#endif
Fred Drakec9680921999-12-13 16:37:25 +00007985#ifdef _SC_SPLIT_CACHE
7986 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7987#endif
7988#ifdef _SC_SSIZE_MAX
7989 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7990#endif
7991#ifdef _SC_STACK_PROT
7992 {"SC_STACK_PROT", _SC_STACK_PROT},
7993#endif
7994#ifdef _SC_STREAM_MAX
7995 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7996#endif
7997#ifdef _SC_SYNCHRONIZED_IO
7998 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7999#endif
8000#ifdef _SC_THREADS
8001 {"SC_THREADS", _SC_THREADS},
8002#endif
8003#ifdef _SC_THREAD_ATTR_STACKADDR
8004 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
8005#endif
8006#ifdef _SC_THREAD_ATTR_STACKSIZE
8007 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
8008#endif
8009#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
8010 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
8011#endif
8012#ifdef _SC_THREAD_KEYS_MAX
8013 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
8014#endif
8015#ifdef _SC_THREAD_PRIORITY_SCHEDULING
8016 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
8017#endif
8018#ifdef _SC_THREAD_PRIO_INHERIT
8019 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
8020#endif
8021#ifdef _SC_THREAD_PRIO_PROTECT
8022 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
8023#endif
8024#ifdef _SC_THREAD_PROCESS_SHARED
8025 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
8026#endif
8027#ifdef _SC_THREAD_SAFE_FUNCTIONS
8028 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
8029#endif
8030#ifdef _SC_THREAD_STACK_MIN
8031 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
8032#endif
8033#ifdef _SC_THREAD_THREADS_MAX
8034 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
8035#endif
8036#ifdef _SC_TIMERS
8037 {"SC_TIMERS", _SC_TIMERS},
8038#endif
8039#ifdef _SC_TIMER_MAX
8040 {"SC_TIMER_MAX", _SC_TIMER_MAX},
8041#endif
8042#ifdef _SC_TTY_NAME_MAX
8043 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
8044#endif
8045#ifdef _SC_TZNAME_MAX
8046 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
8047#endif
8048#ifdef _SC_T_IOV_MAX
8049 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
8050#endif
8051#ifdef _SC_UCHAR_MAX
8052 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
8053#endif
8054#ifdef _SC_UINT_MAX
8055 {"SC_UINT_MAX", _SC_UINT_MAX},
8056#endif
8057#ifdef _SC_UIO_MAXIOV
8058 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
8059#endif
8060#ifdef _SC_ULONG_MAX
8061 {"SC_ULONG_MAX", _SC_ULONG_MAX},
8062#endif
8063#ifdef _SC_USHRT_MAX
8064 {"SC_USHRT_MAX", _SC_USHRT_MAX},
8065#endif
8066#ifdef _SC_VERSION
8067 {"SC_VERSION", _SC_VERSION},
8068#endif
8069#ifdef _SC_WORD_BIT
8070 {"SC_WORD_BIT", _SC_WORD_BIT},
8071#endif
8072#ifdef _SC_XBS5_ILP32_OFF32
8073 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
8074#endif
8075#ifdef _SC_XBS5_ILP32_OFFBIG
8076 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
8077#endif
8078#ifdef _SC_XBS5_LP64_OFF64
8079 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
8080#endif
8081#ifdef _SC_XBS5_LPBIG_OFFBIG
8082 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
8083#endif
8084#ifdef _SC_XOPEN_CRYPT
8085 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
8086#endif
8087#ifdef _SC_XOPEN_ENH_I18N
8088 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
8089#endif
8090#ifdef _SC_XOPEN_LEGACY
8091 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
8092#endif
8093#ifdef _SC_XOPEN_REALTIME
8094 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
8095#endif
8096#ifdef _SC_XOPEN_REALTIME_THREADS
8097 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
8098#endif
8099#ifdef _SC_XOPEN_SHM
8100 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
8101#endif
8102#ifdef _SC_XOPEN_UNIX
8103 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
8104#endif
8105#ifdef _SC_XOPEN_VERSION
8106 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
8107#endif
8108#ifdef _SC_XOPEN_XCU_VERSION
8109 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
8110#endif
8111#ifdef _SC_XOPEN_XPG2
8112 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
8113#endif
8114#ifdef _SC_XOPEN_XPG3
8115 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
8116#endif
8117#ifdef _SC_XOPEN_XPG4
8118 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
8119#endif
8120};
8121
8122static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008123conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008124{
8125 return conv_confname(arg, valuep, posix_constants_sysconf,
8126 sizeof(posix_constants_sysconf)
8127 / sizeof(struct constdef));
8128}
8129
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008130PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008131"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008132Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008133
8134static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008135posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008136{
8137 PyObject *result = NULL;
8138 int name;
8139
8140 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
8141 int value;
8142
8143 errno = 0;
8144 value = sysconf(name);
8145 if (value == -1 && errno != 0)
8146 posix_error();
8147 else
8148 result = PyInt_FromLong(value);
8149 }
8150 return result;
8151}
8152#endif
8153
8154
Fred Drakebec628d1999-12-15 18:31:10 +00008155/* This code is used to ensure that the tables of configuration value names
8156 * are in sorted order as required by conv_confname(), and also to build the
8157 * the exported dictionaries that are used to publish information about the
8158 * names available on the host platform.
8159 *
8160 * Sorting the table at runtime ensures that the table is properly ordered
8161 * when used, even for platforms we're not able to test on. It also makes
8162 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008163 */
Fred Drakebec628d1999-12-15 18:31:10 +00008164
8165static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008166cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008167{
8168 const struct constdef *c1 =
8169 (const struct constdef *) v1;
8170 const struct constdef *c2 =
8171 (const struct constdef *) v2;
8172
8173 return strcmp(c1->name, c2->name);
8174}
8175
8176static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008177setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008178 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008179{
Fred Drakebec628d1999-12-15 18:31:10 +00008180 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008181 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008182
8183 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8184 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008185 if (d == NULL)
8186 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008187
Barry Warsaw3155db32000-04-13 15:20:40 +00008188 for (i=0; i < tablesize; ++i) {
8189 PyObject *o = PyInt_FromLong(table[i].value);
8190 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8191 Py_XDECREF(o);
8192 Py_DECREF(d);
8193 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008194 }
Barry Warsaw3155db32000-04-13 15:20:40 +00008195 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008196 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008197 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008198}
8199
Fred Drakebec628d1999-12-15 18:31:10 +00008200/* Return -1 on failure, 0 on success. */
8201static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008202setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008203{
8204#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008205 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008206 sizeof(posix_constants_pathconf)
8207 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008208 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008209 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008210#endif
8211#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008212 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008213 sizeof(posix_constants_confstr)
8214 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008215 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008216 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008217#endif
8218#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008219 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008220 sizeof(posix_constants_sysconf)
8221 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008222 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008223 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008224#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008225 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008226}
Fred Draked86ed291999-12-15 15:34:33 +00008227
8228
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008229PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008230"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008231Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008232in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008233
8234static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008235posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008236{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008237 abort();
8238 /*NOTREACHED*/
8239 Py_FatalError("abort() called from Python code didn't abort!");
8240 return NULL;
8241}
Fred Drakebec628d1999-12-15 18:31:10 +00008242
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008243#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008244PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008245"startfile(filepath [, operation]) - Start a file with its associated\n\
8246application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008247\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008248When \"operation\" is not specified or \"open\", this acts like\n\
8249double-clicking the file in Explorer, or giving the file name as an\n\
8250argument to the DOS \"start\" command: the file is opened with whatever\n\
8251application (if any) its extension is associated.\n\
8252When another \"operation\" is given, it specifies what should be done with\n\
8253the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008254\n\
8255startfile returns as soon as the associated application is launched.\n\
8256There is no option to wait for the application to close, and no way\n\
8257to retrieve the application's exit status.\n\
8258\n\
8259The filepath is relative to the current directory. If you want to use\n\
8260an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008261the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008262
8263static PyObject *
8264win32_startfile(PyObject *self, PyObject *args)
8265{
8266 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00008267 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008268 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008269
Georg Brandlad89dc82006-04-03 12:26:26 +00008270 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008271 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00008272 if (!PyArg_ParseTuple(args, "U|s:startfile",
8273 &unipath, &operation)) {
8274 PyErr_Clear();
8275 goto normal;
8276 }
8277
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008278
8279 if (operation) {
8280 woperation = PyUnicode_DecodeASCII(operation,
8281 strlen(operation), NULL);
8282 if (!woperation) {
8283 PyErr_Clear();
8284 operation = NULL;
8285 goto normal;
8286 }
Georg Brandlad89dc82006-04-03 12:26:26 +00008287 }
8288
8289 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008290 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00008291 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00008292 NULL, NULL, SW_SHOWNORMAL);
8293 Py_END_ALLOW_THREADS
8294
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008295 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00008296 if (rc <= (HINSTANCE)32) {
8297 PyObject *errval = win32_error_unicode("startfile",
8298 PyUnicode_AS_UNICODE(unipath));
8299 return errval;
8300 }
8301 Py_INCREF(Py_None);
8302 return Py_None;
8303 }
Georg Brandlad89dc82006-04-03 12:26:26 +00008304
8305normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00008306 if (!PyArg_ParseTuple(args, "et|s:startfile",
8307 Py_FileSystemDefaultEncoding, &filepath,
8308 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00008309 return NULL;
8310 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00008311 rc = ShellExecute((HWND)0, operation, filepath,
8312 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008313 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00008314 if (rc <= (HINSTANCE)32) {
8315 PyObject *errval = win32_error("startfile", filepath);
8316 PyMem_Free(filepath);
8317 return errval;
8318 }
8319 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008320 Py_INCREF(Py_None);
8321 return Py_None;
8322}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008323#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008324
Martin v. Löwis438b5342002-12-27 10:16:42 +00008325#ifdef HAVE_GETLOADAVG
8326PyDoc_STRVAR(posix_getloadavg__doc__,
8327"getloadavg() -> (float, float, float)\n\n\
8328Return the number of processes in the system run queue averaged over\n\
8329the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8330was unobtainable");
8331
8332static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008333posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008334{
8335 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008336 if (getloadavg(loadavg, 3)!=3) {
8337 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8338 return NULL;
8339 } else
8340 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8341}
8342#endif
8343
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008344#ifdef MS_WINDOWS
8345
8346PyDoc_STRVAR(win32_urandom__doc__,
8347"urandom(n) -> str\n\n\
8348Return a string of n random bytes suitable for cryptographic use.");
8349
8350typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8351 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8352 DWORD dwFlags );
8353typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8354 BYTE *pbBuffer );
8355
8356static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008357/* This handle is never explicitly released. Instead, the operating
8358 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008359static HCRYPTPROV hCryptProv = 0;
8360
Tim Peters4ad82172004-08-30 17:02:04 +00008361static PyObject*
8362win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008363{
Tim Petersd3115382004-08-30 17:36:46 +00008364 int howMany;
8365 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008366
Tim Peters4ad82172004-08-30 17:02:04 +00008367 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00008368 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00008369 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00008370 if (howMany < 0)
8371 return PyErr_Format(PyExc_ValueError,
8372 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008373
Tim Peters4ad82172004-08-30 17:02:04 +00008374 if (hCryptProv == 0) {
8375 HINSTANCE hAdvAPI32 = NULL;
8376 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008377
Tim Peters4ad82172004-08-30 17:02:04 +00008378 /* Obtain handle to the DLL containing CryptoAPI
8379 This should not fail */
8380 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8381 if(hAdvAPI32 == NULL)
8382 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008383
Tim Peters4ad82172004-08-30 17:02:04 +00008384 /* Obtain pointers to the CryptoAPI functions
8385 This will fail on some early versions of Win95 */
8386 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8387 hAdvAPI32,
8388 "CryptAcquireContextA");
8389 if (pCryptAcquireContext == NULL)
8390 return PyErr_Format(PyExc_NotImplementedError,
8391 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008392
Tim Peters4ad82172004-08-30 17:02:04 +00008393 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8394 hAdvAPI32, "CryptGenRandom");
Georg Brandl74bb7832006-09-06 06:03:59 +00008395 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00008396 return PyErr_Format(PyExc_NotImplementedError,
8397 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008398
Tim Peters4ad82172004-08-30 17:02:04 +00008399 /* Acquire context */
8400 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8401 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8402 return win32_error("CryptAcquireContext", NULL);
8403 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008404
Tim Peters4ad82172004-08-30 17:02:04 +00008405 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008406 result = PyString_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00008407 if (result != NULL) {
8408 /* Get random data */
Amaury Forgeot d'Arc74bd40d2008-07-21 21:06:46 +00008409 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00008410 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008411 PyString_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00008412 Py_DECREF(result);
8413 return win32_error("CryptGenRandom", NULL);
8414 }
Tim Peters4ad82172004-08-30 17:02:04 +00008415 }
Tim Petersd3115382004-08-30 17:36:46 +00008416 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008417}
8418#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008419
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008420#ifdef __VMS
8421/* Use openssl random routine */
8422#include <openssl/rand.h>
8423PyDoc_STRVAR(vms_urandom__doc__,
8424"urandom(n) -> str\n\n\
8425Return a string of n random bytes suitable for cryptographic use.");
8426
8427static PyObject*
8428vms_urandom(PyObject *self, PyObject *args)
8429{
8430 int howMany;
8431 PyObject* result;
8432
8433 /* Read arguments */
8434 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8435 return NULL;
8436 if (howMany < 0)
8437 return PyErr_Format(PyExc_ValueError,
8438 "negative argument not allowed");
8439
8440 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008441 result = PyString_FromStringAndSize(NULL, howMany);
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008442 if (result != NULL) {
8443 /* Get random data */
8444 if (RAND_pseudo_bytes((unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008445 PyString_AS_STRING(result),
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008446 howMany) < 0) {
8447 Py_DECREF(result);
8448 return PyErr_Format(PyExc_ValueError,
8449 "RAND_pseudo_bytes");
8450 }
8451 }
8452 return result;
8453}
8454#endif
8455
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008456static PyMethodDef posix_methods[] = {
8457 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8458#ifdef HAVE_TTYNAME
8459 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8460#endif
8461 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008462#ifdef HAVE_CHFLAGS
8463 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8464#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008465 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008466#ifdef HAVE_FCHMOD
8467 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8468#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008469#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008470 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008471#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008472#ifdef HAVE_LCHMOD
8473 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8474#endif /* HAVE_LCHMOD */
8475#ifdef HAVE_FCHOWN
8476 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8477#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008478#ifdef HAVE_LCHFLAGS
8479 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8480#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008481#ifdef HAVE_LCHOWN
8482 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8483#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008484#ifdef HAVE_CHROOT
8485 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8486#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008487#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00008488 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008489#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008490#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00008491 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008492#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00008493 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008494#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008495#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008496#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008497 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008498#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008499 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8500 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8501 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008502#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008503 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008504#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008505#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008506 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008507#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008508 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8509 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8510 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008511 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008512#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008513 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008514#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008515#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008516 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008517#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008518 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008519#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00008520 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008521#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008522 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8523 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8524 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008525#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00008526 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008527#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008528 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008529#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008530 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8531 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008532#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008533#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008534 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8535 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008536#if defined(PYOS_OS2)
8537 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8538 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8539#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008540#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008541#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008542 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008543#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008544#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008545 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008546#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008547#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008548 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008549#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008550#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008551 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008552#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008553#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008554 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008555#endif /* HAVE_GETEGID */
8556#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008557 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008558#endif /* HAVE_GETEUID */
8559#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008560 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008561#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008562#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008563 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008564#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008565 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008566#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008567 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008568#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008569#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008570 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008571#endif /* HAVE_GETPPID */
8572#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008573 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008574#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008575#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008576 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008577#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008578#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008579 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008580#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008581#ifdef HAVE_KILLPG
8582 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8583#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008584#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008585 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008586#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008587#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008588 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008589#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008590 {"popen2", win32_popen2, METH_VARARGS},
8591 {"popen3", win32_popen3, METH_VARARGS},
8592 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008593 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008594#else
8595#if defined(PYOS_OS2) && defined(PYCC_GCC)
8596 {"popen2", os2emx_popen2, METH_VARARGS},
8597 {"popen3", os2emx_popen3, METH_VARARGS},
8598 {"popen4", os2emx_popen4, METH_VARARGS},
8599#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008600#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008601#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008602#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008603 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008604#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008605#ifdef HAVE_SETEUID
8606 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8607#endif /* HAVE_SETEUID */
8608#ifdef HAVE_SETEGID
8609 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8610#endif /* HAVE_SETEGID */
8611#ifdef HAVE_SETREUID
8612 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8613#endif /* HAVE_SETREUID */
8614#ifdef HAVE_SETREGID
8615 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8616#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008617#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008618 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008619#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008620#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008621 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008622#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008623#ifdef HAVE_GETPGID
8624 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8625#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008626#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008627 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008628#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008629#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008630 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008631#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008632#ifdef HAVE_WAIT3
8633 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8634#endif /* HAVE_WAIT3 */
8635#ifdef HAVE_WAIT4
8636 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8637#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008638#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008639 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008640#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008641#ifdef HAVE_GETSID
8642 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8643#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008644#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008645 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008646#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008647#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008648 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008649#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008650#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008651 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008652#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008653#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008654 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008655#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008656 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8657 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Georg Brandl309501a2008-01-19 20:22:13 +00008658 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008659 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8660 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8661 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8662 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8663 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8664 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8665 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008666 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008667#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008668 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008669#endif
8670#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008671 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008672#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008673#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008674 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8675#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008676#ifdef HAVE_DEVICE_MACROS
8677 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8678 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8679 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8680#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008681#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008682 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008683#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008684#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008685 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008686#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008687#ifdef HAVE_UNSETENV
8688 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8689#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008690 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008691#ifdef HAVE_FCHDIR
8692 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8693#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008694#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008695 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008696#endif
8697#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008698 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008699#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008700#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008701#ifdef WCOREDUMP
8702 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8703#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008704#ifdef WIFCONTINUED
8705 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8706#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008707#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008708 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008709#endif /* WIFSTOPPED */
8710#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008711 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008712#endif /* WIFSIGNALED */
8713#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008714 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008715#endif /* WIFEXITED */
8716#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008717 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008718#endif /* WEXITSTATUS */
8719#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008720 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008721#endif /* WTERMSIG */
8722#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008723 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008724#endif /* WSTOPSIG */
8725#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008726#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008727 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008728#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008729#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008730 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008731#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008732#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008733 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008734#endif
8735#ifdef HAVE_TEMPNAM
8736 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8737#endif
8738#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008739 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008740#endif
Fred Drakec9680921999-12-13 16:37:25 +00008741#ifdef HAVE_CONFSTR
8742 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8743#endif
8744#ifdef HAVE_SYSCONF
8745 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8746#endif
8747#ifdef HAVE_FPATHCONF
8748 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8749#endif
8750#ifdef HAVE_PATHCONF
8751 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8752#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008753 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008754#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008755 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8756#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008757#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008758 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008759#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008760 #ifdef MS_WINDOWS
8761 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8762 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008763 #ifdef __VMS
8764 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8765 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008766 {NULL, NULL} /* Sentinel */
8767};
8768
8769
Barry Warsaw4a342091996-12-19 23:50:02 +00008770static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008771ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008772{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008773 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008774}
8775
Guido van Rossumd48f2521997-12-05 22:19:34 +00008776#if defined(PYOS_OS2)
8777/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008778static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008779{
8780 APIRET rc;
8781 ULONG values[QSV_MAX+1];
8782 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008783 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008784
8785 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008786 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008787 Py_END_ALLOW_THREADS
8788
8789 if (rc != NO_ERROR) {
8790 os2_error(rc);
8791 return -1;
8792 }
8793
Fred Drake4d1e64b2002-04-15 19:40:07 +00008794 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8795 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8796 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8797 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8798 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8799 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8800 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008801
8802 switch (values[QSV_VERSION_MINOR]) {
8803 case 0: ver = "2.00"; break;
8804 case 10: ver = "2.10"; break;
8805 case 11: ver = "2.11"; break;
8806 case 30: ver = "3.00"; break;
8807 case 40: ver = "4.00"; break;
8808 case 50: ver = "5.00"; break;
8809 default:
Tim Peters885d4572001-11-28 20:27:42 +00008810 PyOS_snprintf(tmp, sizeof(tmp),
8811 "%d-%d", values[QSV_VERSION_MAJOR],
8812 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008813 ver = &tmp[0];
8814 }
8815
8816 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008817 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008818 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008819
8820 /* Add Indicator of Which Drive was Used to Boot the System */
8821 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8822 tmp[1] = ':';
8823 tmp[2] = '\0';
8824
Fred Drake4d1e64b2002-04-15 19:40:07 +00008825 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008826}
8827#endif
8828
Barry Warsaw4a342091996-12-19 23:50:02 +00008829static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008830all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008831{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008832#ifdef F_OK
8833 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008834#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008835#ifdef R_OK
8836 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008837#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008838#ifdef W_OK
8839 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008840#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008841#ifdef X_OK
8842 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008843#endif
Fred Drakec9680921999-12-13 16:37:25 +00008844#ifdef NGROUPS_MAX
8845 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8846#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008847#ifdef TMP_MAX
8848 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8849#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008850#ifdef WCONTINUED
8851 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8852#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008853#ifdef WNOHANG
8854 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008855#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008856#ifdef WUNTRACED
8857 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8858#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008859#ifdef O_RDONLY
8860 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8861#endif
8862#ifdef O_WRONLY
8863 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8864#endif
8865#ifdef O_RDWR
8866 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8867#endif
8868#ifdef O_NDELAY
8869 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8870#endif
8871#ifdef O_NONBLOCK
8872 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8873#endif
8874#ifdef O_APPEND
8875 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8876#endif
8877#ifdef O_DSYNC
8878 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8879#endif
8880#ifdef O_RSYNC
8881 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8882#endif
8883#ifdef O_SYNC
8884 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8885#endif
8886#ifdef O_NOCTTY
8887 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8888#endif
8889#ifdef O_CREAT
8890 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8891#endif
8892#ifdef O_EXCL
8893 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8894#endif
8895#ifdef O_TRUNC
8896 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8897#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008898#ifdef O_BINARY
8899 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8900#endif
8901#ifdef O_TEXT
8902 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8903#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008904#ifdef O_LARGEFILE
8905 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8906#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008907#ifdef O_SHLOCK
8908 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8909#endif
8910#ifdef O_EXLOCK
8911 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8912#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008913
Tim Peters5aa91602002-01-30 05:46:57 +00008914/* MS Windows */
8915#ifdef O_NOINHERIT
8916 /* Don't inherit in child processes. */
8917 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8918#endif
8919#ifdef _O_SHORT_LIVED
8920 /* Optimize for short life (keep in memory). */
8921 /* MS forgot to define this one with a non-underscore form too. */
8922 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8923#endif
8924#ifdef O_TEMPORARY
8925 /* Automatically delete when last handle is closed. */
8926 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8927#endif
8928#ifdef O_RANDOM
8929 /* Optimize for random access. */
8930 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8931#endif
8932#ifdef O_SEQUENTIAL
8933 /* Optimize for sequential access. */
8934 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8935#endif
8936
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008937/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00008938#ifdef O_ASYNC
8939 /* Send a SIGIO signal whenever input or output
8940 becomes available on file descriptor */
8941 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8942#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008943#ifdef O_DIRECT
8944 /* Direct disk access. */
8945 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8946#endif
8947#ifdef O_DIRECTORY
8948 /* Must be a directory. */
8949 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8950#endif
8951#ifdef O_NOFOLLOW
8952 /* Do not follow links. */
8953 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8954#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00008955#ifdef O_NOATIME
8956 /* Do not update the access time. */
8957 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8958#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008959
Barry Warsaw5676bd12003-01-07 20:57:09 +00008960 /* These come from sysexits.h */
8961#ifdef EX_OK
8962 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008963#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008964#ifdef EX_USAGE
8965 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008966#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008967#ifdef EX_DATAERR
8968 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008969#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008970#ifdef EX_NOINPUT
8971 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008972#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008973#ifdef EX_NOUSER
8974 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008975#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008976#ifdef EX_NOHOST
8977 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008978#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008979#ifdef EX_UNAVAILABLE
8980 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008981#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008982#ifdef EX_SOFTWARE
8983 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008984#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008985#ifdef EX_OSERR
8986 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008987#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008988#ifdef EX_OSFILE
8989 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008990#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008991#ifdef EX_CANTCREAT
8992 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008993#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008994#ifdef EX_IOERR
8995 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008996#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008997#ifdef EX_TEMPFAIL
8998 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008999#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009000#ifdef EX_PROTOCOL
9001 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009002#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009003#ifdef EX_NOPERM
9004 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009005#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009006#ifdef EX_CONFIG
9007 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009008#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009009#ifdef EX_NOTFOUND
9010 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009011#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009012
Guido van Rossum246bc171999-02-01 23:54:31 +00009013#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009014#if defined(PYOS_OS2) && defined(PYCC_GCC)
9015 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9016 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9017 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9018 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9019 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9020 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9021 if (ins(d, "P_PM", (long)P_PM)) return -1;
9022 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9023 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9024 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9025 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9026 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9027 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9028 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9029 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9030 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9031 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9032 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9033 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9034 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
9035#else
Guido van Rossum7d385291999-02-16 19:38:04 +00009036 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9037 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9038 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9039 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9040 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009041#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009042#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009043
Guido van Rossumd48f2521997-12-05 22:19:34 +00009044#if defined(PYOS_OS2)
9045 if (insertvalues(d)) return -1;
9046#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009047 return 0;
9048}
9049
9050
Tim Peters5aa91602002-01-30 05:46:57 +00009051#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009052#define INITFUNC initnt
9053#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009054
9055#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009056#define INITFUNC initos2
9057#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009058
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009059#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009060#define INITFUNC initposix
9061#define MODNAME "posix"
9062#endif
9063
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009064PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009065INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009066{
Fred Drake4d1e64b2002-04-15 19:40:07 +00009067 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009068
Fred Drake4d1e64b2002-04-15 19:40:07 +00009069 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009070 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00009071 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00009072 if (m == NULL)
9073 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009074
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009075 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009076 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00009077 Py_XINCREF(v);
9078 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009079 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00009080 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009081
Fred Drake4d1e64b2002-04-15 19:40:07 +00009082 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00009083 return;
9084
Fred Drake4d1e64b2002-04-15 19:40:07 +00009085 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00009086 return;
9087
Fred Drake4d1e64b2002-04-15 19:40:07 +00009088 Py_INCREF(PyExc_OSError);
9089 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009090
Guido van Rossumb3d39562000-01-31 18:41:26 +00009091#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00009092 if (posix_putenv_garbage == NULL)
9093 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009094#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009095
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009096 if (!initialized) {
9097 stat_result_desc.name = MODNAME ".stat_result";
9098 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9099 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9100 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9101 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9102 structseq_new = StatResultType.tp_new;
9103 StatResultType.tp_new = statresult_new;
9104
9105 statvfs_result_desc.name = MODNAME ".statvfs_result";
9106 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009107#ifdef NEED_TICKS_PER_SECOND
9108# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
9109 ticks_per_second = sysconf(_SC_CLK_TCK);
9110# elif defined(HZ)
9111 ticks_per_second = HZ;
9112# else
9113 ticks_per_second = 60; /* magic fallback value; may be bogus */
9114# endif
9115#endif
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009116 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009117 Py_INCREF((PyObject*) &StatResultType);
9118 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00009119 Py_INCREF((PyObject*) &StatVFSResultType);
9120 PyModule_AddObject(m, "statvfs_result",
9121 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009122 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009123
9124#ifdef __APPLE__
9125 /*
9126 * Step 2 of weak-linking support on Mac OS X.
9127 *
9128 * The code below removes functions that are not available on the
9129 * currently active platform.
9130 *
9131 * This block allow one to use a python binary that was build on
9132 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9133 * OSX 10.4.
9134 */
9135#ifdef HAVE_FSTATVFS
9136 if (fstatvfs == NULL) {
9137 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9138 return;
9139 }
9140 }
9141#endif /* HAVE_FSTATVFS */
9142
9143#ifdef HAVE_STATVFS
9144 if (statvfs == NULL) {
9145 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9146 return;
9147 }
9148 }
9149#endif /* HAVE_STATVFS */
9150
9151# ifdef HAVE_LCHOWN
9152 if (lchown == NULL) {
9153 if (PyObject_DelAttrString(m, "lchown") == -1) {
9154 return;
9155 }
9156 }
9157#endif /* HAVE_LCHOWN */
9158
9159
9160#endif /* __APPLE__ */
9161
Guido van Rossumb6775db1994-08-01 11:34:53 +00009162}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009163
9164#ifdef __cplusplus
9165}
9166#endif
9167
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009168