blob: eb8083f0eda53561e5ae6fd02c689d26ca40750e [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"
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000273#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000274#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000275#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000276#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277
Guido van Rossumd48f2521997-12-05 22:19:34 +0000278#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000280#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281
Tim Petersbc2e10e2002-03-03 23:17:02 +0000282#ifndef MAXPATHLEN
Thomas Wouters1ddba602006-04-25 15:29:46 +0000283#if defined(PATH_MAX) && PATH_MAX > 1024
284#define MAXPATHLEN PATH_MAX
285#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000286#define MAXPATHLEN 1024
Thomas Wouters1ddba602006-04-25 15:29:46 +0000287#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000288#endif /* MAXPATHLEN */
289
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000290#ifdef UNION_WAIT
291/* Emulate some macros on systems that have a union instead of macros */
292
293#ifndef WIFEXITED
294#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
295#endif
296
297#ifndef WEXITSTATUS
298#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
299#endif
300
301#ifndef WTERMSIG
302#define WTERMSIG(u_wait) ((u_wait).w_termsig)
303#endif
304
Neal Norwitzd5a37542006-03-20 06:48:34 +0000305#define WAIT_TYPE union wait
306#define WAIT_STATUS_INT(s) (s.w_status)
307
308#else /* !UNION_WAIT */
309#define WAIT_TYPE int
310#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000311#endif /* UNION_WAIT */
312
Antoine Pitrou794b3fc2009-05-23 15:47:13 +0000313/* Issue #1983: pid_t can be longer than a C long on some systems */
Antoine Pitrou6c95acb2009-05-24 12:17:07 +0000314#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
Antoine Pitrou794b3fc2009-05-23 15:47:13 +0000315#define PARSE_PID "i"
316#define PyLong_FromPid PyInt_FromLong
317#define PyLong_AsPid PyInt_AsLong
318#elif SIZEOF_PID_T == SIZEOF_LONG
319#define PARSE_PID "l"
320#define PyLong_FromPid PyInt_FromLong
321#define PyLong_AsPid PyInt_AsLong
322#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
323#define PARSE_PID "L"
324#define PyLong_FromPid PyLong_FromLongLong
325#define PyLong_AsPid PyInt_AsLongLong
326#else
327#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
Antoine Pitrou794b3fc2009-05-23 15:47:13 +0000328#endif /* SIZEOF_PID_T */
329
Greg Wardb48bc172000-03-01 21:51:56 +0000330/* Don't use the "_r" form if we don't need it (also, won't have a
331 prototype for it, at least on Solaris -- maybe others as well?). */
332#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
333#define USE_CTERMID_R
334#endif
335
336#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
337#define USE_TMPNAM_R
338#endif
339
Fred Drake699f3522000-06-29 21:12:41 +0000340/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000341#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000342#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000343# define STAT win32_stat
344# define FSTAT win32_fstat
345# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000346#else
347# define STAT stat
348# define FSTAT fstat
349# define STRUCT_STAT struct stat
350#endif
351
Tim Peters11b23062003-04-23 02:39:17 +0000352#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000353#include <sys/mkdev.h>
354#else
355#if defined(MAJOR_IN_SYSMACROS)
356#include <sys/sysmacros.h>
357#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000358#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
359#include <sys/mkdev.h>
360#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000361#endif
Fred Drake699f3522000-06-29 21:12:41 +0000362
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000363/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000364#ifdef WITH_NEXT_FRAMEWORK
365/* On Darwin/MacOSX a shared library or framework has no access to
366** environ directly, we must obtain it with _NSGetEnviron().
367*/
368#include <crt_externs.h>
369static char **environ;
370#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000371extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000372#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000373
Barry Warsaw53699e91996-12-10 23:23:01 +0000374static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000375convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000376{
Barry Warsaw53699e91996-12-10 23:23:01 +0000377 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000378 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000379 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000380 if (d == NULL)
381 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000382#ifdef WITH_NEXT_FRAMEWORK
383 if (environ == NULL)
384 environ = *_NSGetEnviron();
385#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000386 if (environ == NULL)
387 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000388 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000390 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000391 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000392 char *p = strchr(*e, '=');
393 if (p == NULL)
394 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000395 k = PyString_FromStringAndSize(*e, (int)(p-*e));
Guido van Rossum6a619f41999-08-03 19:41:10 +0000396 if (k == NULL) {
397 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000398 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000399 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000400 v = PyString_FromString(p+1);
Guido van Rossum6a619f41999-08-03 19:41:10 +0000401 if (v == NULL) {
402 PyErr_Clear();
403 Py_DECREF(k);
404 continue;
405 }
406 if (PyDict_GetItem(d, k) == NULL) {
407 if (PyDict_SetItem(d, k, v) != 0)
408 PyErr_Clear();
409 }
410 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000411 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000412 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000413#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000414 {
415 APIRET rc;
416 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
417
418 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000419 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000420 PyObject *v = PyString_FromString(buffer);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000421 PyDict_SetItemString(d, "BEGINLIBPATH", v);
422 Py_DECREF(v);
423 }
424 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
425 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000426 PyObject *v = PyString_FromString(buffer);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000427 PyDict_SetItemString(d, "ENDLIBPATH", v);
428 Py_DECREF(v);
429 }
430 }
431#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000432 return d;
433}
434
435
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000436/* Set a POSIX-specific error from errno, and return NULL */
437
Barry Warsawd58d7641998-07-23 16:14:40 +0000438static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000439posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000440{
Barry Warsawca74da41999-02-09 19:31:45 +0000441 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000442}
Barry Warsawd58d7641998-07-23 16:14:40 +0000443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000444posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000445{
Barry Warsawca74da41999-02-09 19:31:45 +0000446 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000447}
448
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000449#ifdef Py_WIN_WIDE_FILENAMES
450static PyObject *
451posix_error_with_unicode_filename(Py_UNICODE* name)
452{
453 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
454}
455#endif /* Py_WIN_WIDE_FILENAMES */
456
457
Mark Hammondef8b6542001-05-13 08:04:26 +0000458static PyObject *
459posix_error_with_allocated_filename(char* name)
460{
461 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
462 PyMem_Free(name);
463 return rc;
464}
465
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000466#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000467static PyObject *
468win32_error(char* function, char* filename)
469{
Mark Hammond33a6da92000-08-15 00:46:38 +0000470 /* XXX We should pass the function name along in the future.
471 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000472 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000473 Windows error object, which is non-trivial.
474 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000475 errno = GetLastError();
476 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000477 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000478 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000479 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000480}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000481
482#ifdef Py_WIN_WIDE_FILENAMES
483static PyObject *
484win32_error_unicode(char* function, Py_UNICODE* filename)
485{
486 /* XXX - see win32_error for comments on 'function' */
487 errno = GetLastError();
488 if (filename)
489 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
490 else
491 return PyErr_SetFromWindowsErr(errno);
492}
493
494static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
495{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000496}
497
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000498static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000499convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000500{
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000501 if (PyUnicode_CheckExact(*param))
502 Py_INCREF(*param);
503 else if (PyUnicode_Check(*param))
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000504 /* For a Unicode subtype that's not a Unicode object,
505 return a true Unicode object with the same data. */
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000506 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
507 PyUnicode_GET_SIZE(*param));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000508 else
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000509 *param = PyUnicode_FromEncodedObject(*param,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000510 Py_FileSystemDefaultEncoding,
511 "strict");
512 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000513}
514
515#endif /* Py_WIN_WIDE_FILENAMES */
516
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000517#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000518
Guido van Rossumd48f2521997-12-05 22:19:34 +0000519#if defined(PYOS_OS2)
520/**********************************************************************
521 * Helper Function to Trim and Format OS/2 Messages
522 **********************************************************************/
523 static void
524os2_formatmsg(char *msgbuf, int msglen, char *reason)
525{
526 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
527
528 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
529 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
530
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000531 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000532 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
533 }
534
535 /* Add Optional Reason Text */
536 if (reason) {
537 strcat(msgbuf, " : ");
538 strcat(msgbuf, reason);
539 }
540}
541
542/**********************************************************************
543 * Decode an OS/2 Operating System Error Code
544 *
545 * A convenience function to lookup an OS/2 error code and return a
546 * text message we can use to raise a Python exception.
547 *
548 * Notes:
549 * The messages for errors returned from the OS/2 kernel reside in
550 * the file OSO001.MSG in the \OS2 directory hierarchy.
551 *
552 **********************************************************************/
553 static char *
554os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
555{
556 APIRET rc;
557 ULONG msglen;
558
559 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
560 Py_BEGIN_ALLOW_THREADS
561 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
562 errorcode, "oso001.msg", &msglen);
563 Py_END_ALLOW_THREADS
564
565 if (rc == NO_ERROR)
566 os2_formatmsg(msgbuf, msglen, reason);
567 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000568 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000569 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000570
571 return msgbuf;
572}
573
574/* Set an OS/2-specific error and return NULL. OS/2 kernel
575 errors are not in a global variable e.g. 'errno' nor are
576 they congruent with posix error numbers. */
577
578static PyObject * os2_error(int code)
579{
580 char text[1024];
581 PyObject *v;
582
583 os2_strerror(text, sizeof(text), code, "");
584
585 v = Py_BuildValue("(is)", code, text);
586 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000587 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000588 Py_DECREF(v);
589 }
590 return NULL; /* Signal to Python that an Exception is Pending */
591}
592
593#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000594
595/* POSIX generic methods */
596
Barry Warsaw53699e91996-12-10 23:23:01 +0000597static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000598posix_fildes(PyObject *fdobj, int (*func)(int))
599{
600 int fd;
601 int res;
602 fd = PyObject_AsFileDescriptor(fdobj);
603 if (fd < 0)
604 return NULL;
605 Py_BEGIN_ALLOW_THREADS
606 res = (*func)(fd);
607 Py_END_ALLOW_THREADS
608 if (res < 0)
609 return posix_error();
610 Py_INCREF(Py_None);
611 return Py_None;
612}
Guido van Rossum21142a01999-01-08 21:05:37 +0000613
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000614#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000615static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000616unicode_file_names(void)
617{
618 static int canusewide = -1;
619 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000620 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000621 the Windows NT family. */
622 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
623 }
624 return canusewide;
625}
626#endif
Tim Peters11b23062003-04-23 02:39:17 +0000627
Guido van Rossum21142a01999-01-08 21:05:37 +0000628static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000629posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000630{
Mark Hammondef8b6542001-05-13 08:04:26 +0000631 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000632 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000633 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000634 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000635 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000636 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000637 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000638 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000639 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000640 return posix_error_with_allocated_filename(path1);
641 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000642 Py_INCREF(Py_None);
643 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000644}
645
Barry Warsaw53699e91996-12-10 23:23:01 +0000646static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000647posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000648 char *format,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000649 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000650{
Mark Hammondef8b6542001-05-13 08:04:26 +0000651 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000652 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000653 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000654 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000655 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000656 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000657 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000658 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000659 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000660 PyMem_Free(path1);
661 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000662 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000663 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000665 Py_INCREF(Py_None);
666 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000667}
668
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000669#ifdef Py_WIN_WIDE_FILENAMES
670static PyObject*
671win32_1str(PyObject* args, char* func,
672 char* format, BOOL (__stdcall *funcA)(LPCSTR),
673 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
674{
675 PyObject *uni;
676 char *ansi;
677 BOOL result;
678 if (unicode_file_names()) {
679 if (!PyArg_ParseTuple(args, wformat, &uni))
680 PyErr_Clear();
681 else {
682 Py_BEGIN_ALLOW_THREADS
683 result = funcW(PyUnicode_AsUnicode(uni));
684 Py_END_ALLOW_THREADS
685 if (!result)
686 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
687 Py_INCREF(Py_None);
688 return Py_None;
689 }
690 }
691 if (!PyArg_ParseTuple(args, format, &ansi))
692 return NULL;
693 Py_BEGIN_ALLOW_THREADS
694 result = funcA(ansi);
695 Py_END_ALLOW_THREADS
696 if (!result)
697 return win32_error(func, ansi);
698 Py_INCREF(Py_None);
699 return Py_None;
700
701}
702
703/* This is a reimplementation of the C library's chdir function,
704 but one that produces Win32 errors instead of DOS error codes.
705 chdir is essentially a wrapper around SetCurrentDirectory; however,
706 it also needs to set "magic" environment variables indicating
707 the per-drive current directory, which are of the form =<drive>: */
708BOOL __stdcall
709win32_chdir(LPCSTR path)
710{
711 char new_path[MAX_PATH+1];
712 int result;
713 char env[4] = "=x:";
714
715 if(!SetCurrentDirectoryA(path))
716 return FALSE;
717 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
718 if (!result)
719 return FALSE;
720 /* In the ANSI API, there should not be any paths longer
721 than MAX_PATH. */
722 assert(result <= MAX_PATH+1);
723 if (strncmp(new_path, "\\\\", 2) == 0 ||
724 strncmp(new_path, "//", 2) == 0)
725 /* UNC path, nothing to do. */
726 return TRUE;
727 env[1] = new_path[0];
728 return SetEnvironmentVariableA(env, new_path);
729}
730
731/* The Unicode version differs from the ANSI version
732 since the current directory might exceed MAX_PATH characters */
733BOOL __stdcall
734win32_wchdir(LPCWSTR path)
735{
736 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
737 int result;
738 wchar_t env[4] = L"=x:";
739
740 if(!SetCurrentDirectoryW(path))
741 return FALSE;
742 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
743 if (!result)
744 return FALSE;
745 if (result > MAX_PATH+1) {
Hirokazu Yamamoto2c66b7c2008-10-09 18:06:58 +0000746 new_path = malloc(result * sizeof(wchar_t));
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000747 if (!new_path) {
748 SetLastError(ERROR_OUTOFMEMORY);
749 return FALSE;
750 }
Hirokazu Yamamoto2c66b7c2008-10-09 18:06:58 +0000751 result = GetCurrentDirectoryW(result, new_path);
752 if (!result) {
753 free(new_path);
754 return FALSE;
755 }
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000756 }
757 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
758 wcsncmp(new_path, L"//", 2) == 0)
759 /* UNC path, nothing to do. */
760 return TRUE;
761 env[1] = new_path[0];
762 result = SetEnvironmentVariableW(env, new_path);
763 if (new_path != _new_path)
764 free(new_path);
765 return result;
766}
767#endif
768
Martin v. Löwis14694662006-02-03 12:54:16 +0000769#ifdef MS_WINDOWS
770/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
771 - time stamps are restricted to second resolution
772 - file modification times suffer from forth-and-back conversions between
773 UTC and local time
774 Therefore, we implement our own stat, based on the Win32 API directly.
775*/
776#define HAVE_STAT_NSEC 1
777
778struct win32_stat{
779 int st_dev;
780 __int64 st_ino;
781 unsigned short st_mode;
782 int st_nlink;
783 int st_uid;
784 int st_gid;
785 int st_rdev;
786 __int64 st_size;
787 int st_atime;
788 int st_atime_nsec;
789 int st_mtime;
790 int st_mtime_nsec;
791 int st_ctime;
792 int st_ctime_nsec;
793};
794
795static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
796
797static void
798FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
799{
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000800 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
801 /* Cannot simply cast and dereference in_ptr,
802 since it might not be aligned properly */
803 __int64 in;
804 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000805 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
806 /* XXX Win32 supports time stamps past 2038; we currently don't */
807 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
808}
809
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000810static void
811time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
812{
813 /* XXX endianness */
814 __int64 out;
815 out = time_in + secs_between_epochs;
Martin v. Löwisf43893a2006-10-09 20:44:25 +0000816 out = out * 10000000 + nsec_in / 100;
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000817 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000818}
819
Martin v. Löwis14694662006-02-03 12:54:16 +0000820/* Below, we *know* that ugo+r is 0444 */
821#if _S_IREAD != 0400
822#error Unsupported C library
823#endif
824static int
825attributes_to_mode(DWORD attr)
826{
827 int m = 0;
828 if (attr & FILE_ATTRIBUTE_DIRECTORY)
829 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
830 else
831 m |= _S_IFREG;
832 if (attr & FILE_ATTRIBUTE_READONLY)
833 m |= 0444;
834 else
835 m |= 0666;
836 return m;
837}
838
839static int
840attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
841{
842 memset(result, 0, sizeof(*result));
843 result->st_mode = attributes_to_mode(info->dwFileAttributes);
844 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
845 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
846 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
847 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
848
849 return 0;
850}
851
Martin v. Löwis012bc722006-10-15 09:43:39 +0000852/* Emulate GetFileAttributesEx[AW] on Windows 95 */
853static int checked = 0;
854static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
855static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
856static void
857check_gfax()
858{
859 HINSTANCE hKernel32;
860 if (checked)
861 return;
862 checked = 1;
863 hKernel32 = GetModuleHandle("KERNEL32");
864 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
865 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
866}
867
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000868static BOOL
869attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
870{
871 HANDLE hFindFile;
872 WIN32_FIND_DATAA FileData;
873 hFindFile = FindFirstFileA(pszFile, &FileData);
874 if (hFindFile == INVALID_HANDLE_VALUE)
875 return FALSE;
876 FindClose(hFindFile);
877 pfad->dwFileAttributes = FileData.dwFileAttributes;
878 pfad->ftCreationTime = FileData.ftCreationTime;
879 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
880 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
881 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
882 pfad->nFileSizeLow = FileData.nFileSizeLow;
883 return TRUE;
884}
885
886static BOOL
887attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
888{
889 HANDLE hFindFile;
890 WIN32_FIND_DATAW FileData;
891 hFindFile = FindFirstFileW(pszFile, &FileData);
892 if (hFindFile == INVALID_HANDLE_VALUE)
893 return FALSE;
894 FindClose(hFindFile);
895 pfad->dwFileAttributes = FileData.dwFileAttributes;
896 pfad->ftCreationTime = FileData.ftCreationTime;
897 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
898 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
899 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
900 pfad->nFileSizeLow = FileData.nFileSizeLow;
901 return TRUE;
902}
903
Martin v. Löwis012bc722006-10-15 09:43:39 +0000904static BOOL WINAPI
905Py_GetFileAttributesExA(LPCSTR pszFile,
906 GET_FILEEX_INFO_LEVELS level,
907 LPVOID pv)
908{
909 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000910 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
911 /* First try to use the system's implementation, if that is
912 available and either succeeds to gives an error other than
913 that it isn't implemented. */
914 check_gfax();
915 if (gfaxa) {
916 result = gfaxa(pszFile, level, pv);
917 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
918 return result;
919 }
920 /* It's either not present, or not implemented.
921 Emulate using FindFirstFile. */
922 if (level != GetFileExInfoStandard) {
923 SetLastError(ERROR_INVALID_PARAMETER);
924 return FALSE;
925 }
926 /* Use GetFileAttributes to validate that the file name
927 does not contain wildcards (which FindFirstFile would
928 accept). */
929 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
930 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000931 return attributes_from_dir(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +0000932}
933
934static BOOL WINAPI
935Py_GetFileAttributesExW(LPCWSTR pszFile,
936 GET_FILEEX_INFO_LEVELS level,
937 LPVOID pv)
938{
939 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +0000940 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
941 /* First try to use the system's implementation, if that is
942 available and either succeeds to gives an error other than
943 that it isn't implemented. */
944 check_gfax();
945 if (gfaxa) {
946 result = gfaxw(pszFile, level, pv);
947 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
948 return result;
949 }
950 /* It's either not present, or not implemented.
951 Emulate using FindFirstFile. */
952 if (level != GetFileExInfoStandard) {
953 SetLastError(ERROR_INVALID_PARAMETER);
954 return FALSE;
955 }
956 /* Use GetFileAttributes to validate that the file name
957 does not contain wildcards (which FindFirstFile would
958 accept). */
959 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
960 return FALSE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000961 return attributes_from_dir_w(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +0000962}
963
Martin v. Löwis14694662006-02-03 12:54:16 +0000964static int
965win32_stat(const char* path, struct win32_stat *result)
966{
967 WIN32_FILE_ATTRIBUTE_DATA info;
968 int code;
969 char *dot;
970 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +0000971 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000972 if (GetLastError() != ERROR_SHARING_VIOLATION) {
973 /* Protocol violation: we explicitly clear errno, instead of
974 setting it to a POSIX error. Callers should use GetLastError. */
975 errno = 0;
976 return -1;
977 } else {
978 /* Could not get attributes on open file. Fall back to
979 reading the directory. */
980 if (!attributes_from_dir(path, &info)) {
981 /* Very strange. This should not fail now */
982 errno = 0;
983 return -1;
984 }
985 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000986 }
987 code = attribute_data_to_stat(&info, result);
988 if (code != 0)
989 return code;
990 /* Set S_IFEXEC if it is an .exe, .bat, ... */
991 dot = strrchr(path, '.');
992 if (dot) {
993 if (stricmp(dot, ".bat") == 0 ||
994 stricmp(dot, ".cmd") == 0 ||
995 stricmp(dot, ".exe") == 0 ||
996 stricmp(dot, ".com") == 0)
997 result->st_mode |= 0111;
998 }
999 return code;
1000}
1001
1002static int
1003win32_wstat(const wchar_t* path, struct win32_stat *result)
1004{
1005 int code;
1006 const wchar_t *dot;
1007 WIN32_FILE_ATTRIBUTE_DATA info;
1008 /* XXX not supported on Win95 and NT 3.x */
Martin v. Löwis012bc722006-10-15 09:43:39 +00001009 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001010 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1011 /* Protocol violation: we explicitly clear errno, instead of
1012 setting it to a POSIX error. Callers should use GetLastError. */
1013 errno = 0;
1014 return -1;
1015 } else {
1016 /* Could not get attributes on open file. Fall back to
1017 reading the directory. */
1018 if (!attributes_from_dir_w(path, &info)) {
1019 /* Very strange. This should not fail now */
1020 errno = 0;
1021 return -1;
1022 }
1023 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001024 }
1025 code = attribute_data_to_stat(&info, result);
1026 if (code < 0)
1027 return code;
1028 /* Set IFEXEC if it is an .exe, .bat, ... */
1029 dot = wcsrchr(path, '.');
1030 if (dot) {
1031 if (_wcsicmp(dot, L".bat") == 0 ||
1032 _wcsicmp(dot, L".cmd") == 0 ||
1033 _wcsicmp(dot, L".exe") == 0 ||
1034 _wcsicmp(dot, L".com") == 0)
1035 result->st_mode |= 0111;
1036 }
1037 return code;
1038}
1039
1040static int
1041win32_fstat(int file_number, struct win32_stat *result)
1042{
1043 BY_HANDLE_FILE_INFORMATION info;
1044 HANDLE h;
1045 int type;
1046
1047 h = (HANDLE)_get_osfhandle(file_number);
1048
1049 /* Protocol violation: we explicitly clear errno, instead of
1050 setting it to a POSIX error. Callers should use GetLastError. */
1051 errno = 0;
1052
1053 if (h == INVALID_HANDLE_VALUE) {
1054 /* This is really a C library error (invalid file handle).
1055 We set the Win32 error to the closes one matching. */
1056 SetLastError(ERROR_INVALID_HANDLE);
1057 return -1;
1058 }
1059 memset(result, 0, sizeof(*result));
1060
1061 type = GetFileType(h);
1062 if (type == FILE_TYPE_UNKNOWN) {
1063 DWORD error = GetLastError();
1064 if (error != 0) {
1065 return -1;
1066 }
1067 /* else: valid but unknown file */
1068 }
1069
1070 if (type != FILE_TYPE_DISK) {
1071 if (type == FILE_TYPE_CHAR)
1072 result->st_mode = _S_IFCHR;
1073 else if (type == FILE_TYPE_PIPE)
1074 result->st_mode = _S_IFIFO;
1075 return 0;
1076 }
1077
1078 if (!GetFileInformationByHandle(h, &info)) {
1079 return -1;
1080 }
1081
1082 /* similar to stat() */
1083 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1084 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1085 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1086 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1087 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1088 /* specific to fstat() */
1089 result->st_nlink = info.nNumberOfLinks;
1090 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1091 return 0;
1092}
1093
1094#endif /* MS_WINDOWS */
1095
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001096PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001097"stat_result: Result from stat or lstat.\n\n\
1098This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001099 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001100or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1101\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001102Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1103or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001104\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001105See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001106
1107static PyStructSequence_Field stat_result_fields[] = {
1108 {"st_mode", "protection bits"},
1109 {"st_ino", "inode"},
1110 {"st_dev", "device"},
1111 {"st_nlink", "number of hard links"},
1112 {"st_uid", "user ID of owner"},
1113 {"st_gid", "group ID of owner"},
1114 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001115 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1116 {NULL, "integer time of last access"},
1117 {NULL, "integer time of last modification"},
1118 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001119 {"st_atime", "time of last access"},
1120 {"st_mtime", "time of last modification"},
1121 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001122#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001123 {"st_blksize", "blocksize for filesystem I/O"},
1124#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001125#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001126 {"st_blocks", "number of blocks allocated"},
1127#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001128#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001129 {"st_rdev", "device type (if inode device)"},
1130#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001131#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1132 {"st_flags", "user defined flags for file"},
1133#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001134#ifdef HAVE_STRUCT_STAT_ST_GEN
1135 {"st_gen", "generation number"},
1136#endif
1137#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1138 {"st_birthtime", "time of creation"},
1139#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001140 {0}
1141};
1142
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001143#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001144#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001145#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001146#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001147#endif
1148
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001149#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001150#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1151#else
1152#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1153#endif
1154
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001155#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001156#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1157#else
1158#define ST_RDEV_IDX ST_BLOCKS_IDX
1159#endif
1160
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001161#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1162#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1163#else
1164#define ST_FLAGS_IDX ST_RDEV_IDX
1165#endif
1166
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001167#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001168#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001169#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001170#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001171#endif
1172
1173#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1174#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1175#else
1176#define ST_BIRTHTIME_IDX ST_GEN_IDX
1177#endif
1178
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001179static PyStructSequence_Desc stat_result_desc = {
1180 "stat_result", /* name */
1181 stat_result__doc__, /* doc */
1182 stat_result_fields,
1183 10
1184};
1185
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001186PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001187"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1188This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001189 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001190or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001191\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001192See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001193
1194static PyStructSequence_Field statvfs_result_fields[] = {
1195 {"f_bsize", },
1196 {"f_frsize", },
1197 {"f_blocks", },
1198 {"f_bfree", },
1199 {"f_bavail", },
1200 {"f_files", },
1201 {"f_ffree", },
1202 {"f_favail", },
1203 {"f_flag", },
1204 {"f_namemax",},
1205 {0}
1206};
1207
1208static PyStructSequence_Desc statvfs_result_desc = {
1209 "statvfs_result", /* name */
1210 statvfs_result__doc__, /* doc */
1211 statvfs_result_fields,
1212 10
1213};
1214
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001215static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001216static PyTypeObject StatResultType;
1217static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001218static newfunc structseq_new;
1219
1220static PyObject *
1221statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1222{
1223 PyStructSequence *result;
1224 int i;
1225
1226 result = (PyStructSequence*)structseq_new(type, args, kwds);
1227 if (!result)
1228 return NULL;
1229 /* If we have been initialized from a tuple,
1230 st_?time might be set to None. Initialize it
1231 from the int slots. */
1232 for (i = 7; i <= 9; i++) {
1233 if (result->ob_item[i+3] == Py_None) {
1234 Py_DECREF(Py_None);
1235 Py_INCREF(result->ob_item[i]);
1236 result->ob_item[i+3] = result->ob_item[i];
1237 }
1238 }
1239 return (PyObject*)result;
1240}
1241
1242
1243
1244/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001245static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001246
1247PyDoc_STRVAR(stat_float_times__doc__,
1248"stat_float_times([newval]) -> oldval\n\n\
1249Determine whether os.[lf]stat represents time stamps as float objects.\n\
1250If newval is True, future calls to stat() return floats, if it is False,\n\
1251future calls return ints. \n\
1252If newval is omitted, return the current setting.\n");
1253
1254static PyObject*
1255stat_float_times(PyObject* self, PyObject *args)
1256{
1257 int newval = -1;
1258 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1259 return NULL;
1260 if (newval == -1)
1261 /* Return old value */
1262 return PyBool_FromLong(_stat_float_times);
1263 _stat_float_times = newval;
1264 Py_INCREF(Py_None);
1265 return Py_None;
1266}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001267
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001268static void
1269fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1270{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001271 PyObject *fval,*ival;
1272#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001273 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001274#else
1275 ival = PyInt_FromLong((long)sec);
1276#endif
Neal Norwitze0a81af2006-08-12 01:50:38 +00001277 if (!ival)
1278 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001279 if (_stat_float_times) {
1280 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1281 } else {
1282 fval = ival;
1283 Py_INCREF(fval);
1284 }
1285 PyStructSequence_SET_ITEM(v, index, ival);
1286 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001287}
1288
Tim Peters5aa91602002-01-30 05:46:57 +00001289/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001290 (used by posix_stat() and posix_fstat()) */
1291static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001292_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001293{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001294 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001295 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001296 if (v == NULL)
1297 return NULL;
1298
Martin v. Löwis14694662006-02-03 12:54:16 +00001299 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001300#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001301 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001302 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001303#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001304 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001305#endif
1306#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001307 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001308 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001309#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001310 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001311#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001312 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1313 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1314 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001315#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001316 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001317 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001318#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001319 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001320#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001321
Martin v. Löwis14694662006-02-03 12:54:16 +00001322#if defined(HAVE_STAT_TV_NSEC)
1323 ansec = st->st_atim.tv_nsec;
1324 mnsec = st->st_mtim.tv_nsec;
1325 cnsec = st->st_ctim.tv_nsec;
1326#elif defined(HAVE_STAT_TV_NSEC2)
1327 ansec = st->st_atimespec.tv_nsec;
1328 mnsec = st->st_mtimespec.tv_nsec;
1329 cnsec = st->st_ctimespec.tv_nsec;
1330#elif defined(HAVE_STAT_NSEC)
1331 ansec = st->st_atime_nsec;
1332 mnsec = st->st_mtime_nsec;
1333 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001334#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001335 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001336#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001337 fill_time(v, 7, st->st_atime, ansec);
1338 fill_time(v, 8, st->st_mtime, mnsec);
1339 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001340
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001341#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001342 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001343 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001344#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001345#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001346 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001347 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001348#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001349#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001350 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001351 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001352#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001353#ifdef HAVE_STRUCT_STAT_ST_GEN
1354 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001355 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001356#endif
1357#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1358 {
1359 PyObject *val;
1360 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001361 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001362#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001363 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001364#else
1365 bnsec = 0;
1366#endif
1367 if (_stat_float_times) {
1368 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1369 } else {
1370 val = PyInt_FromLong((long)bsec);
1371 }
1372 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1373 val);
1374 }
1375#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001376#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1377 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001378 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001379#endif
Fred Drake699f3522000-06-29 21:12:41 +00001380
1381 if (PyErr_Occurred()) {
1382 Py_DECREF(v);
1383 return NULL;
1384 }
1385
1386 return v;
1387}
1388
Martin v. Löwisd8948722004-06-02 09:57:56 +00001389#ifdef MS_WINDOWS
1390
1391/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1392 where / can be used in place of \ and the trailing slash is optional.
1393 Both SERVER and SHARE must have at least one character.
1394*/
1395
1396#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1397#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001398#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001399#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001400#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001401
Tim Peters4ad82172004-08-30 17:02:04 +00001402static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001403IsUNCRootA(char *path, int pathlen)
1404{
1405 #define ISSLASH ISSLASHA
1406
1407 int i, share;
1408
1409 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1410 /* minimum UNCRoot is \\x\y */
1411 return FALSE;
1412 for (i = 2; i < pathlen ; i++)
1413 if (ISSLASH(path[i])) break;
1414 if (i == 2 || i == pathlen)
1415 /* do not allow \\\SHARE or \\SERVER */
1416 return FALSE;
1417 share = i+1;
1418 for (i = share; i < pathlen; i++)
1419 if (ISSLASH(path[i])) break;
1420 return (i != share && (i == pathlen || i == pathlen-1));
1421
1422 #undef ISSLASH
1423}
1424
1425#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001426static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001427IsUNCRootW(Py_UNICODE *path, int pathlen)
1428{
1429 #define ISSLASH ISSLASHW
1430
1431 int i, share;
1432
1433 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1434 /* minimum UNCRoot is \\x\y */
1435 return FALSE;
1436 for (i = 2; i < pathlen ; i++)
1437 if (ISSLASH(path[i])) break;
1438 if (i == 2 || i == pathlen)
1439 /* do not allow \\\SHARE or \\SERVER */
1440 return FALSE;
1441 share = i+1;
1442 for (i = share; i < pathlen; i++)
1443 if (ISSLASH(path[i])) break;
1444 return (i != share && (i == pathlen || i == pathlen-1));
1445
1446 #undef ISSLASH
1447}
1448#endif /* Py_WIN_WIDE_FILENAMES */
1449#endif /* MS_WINDOWS */
1450
Barry Warsaw53699e91996-12-10 23:23:01 +00001451static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001452posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001453 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001454#ifdef __VMS
1455 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1456#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001457 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001458#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001459 char *wformat,
1460 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001461{
Fred Drake699f3522000-06-29 21:12:41 +00001462 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001463 char *path = NULL; /* pass this to stat; do not free() it */
1464 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001465 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001466 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001467
1468#ifdef Py_WIN_WIDE_FILENAMES
1469 /* If on wide-character-capable OS see if argument
1470 is Unicode and if so use wide API. */
1471 if (unicode_file_names()) {
1472 PyUnicodeObject *po;
1473 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001474 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1475
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001476 Py_BEGIN_ALLOW_THREADS
1477 /* PyUnicode_AS_UNICODE result OK without
1478 thread lock as it is a simple dereference. */
1479 res = wstatfunc(wpath, &st);
1480 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001481
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001482 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001483 return win32_error_unicode("stat", wpath);
1484 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001485 }
1486 /* Drop the argument parsing error as narrow strings
1487 are also valid. */
1488 PyErr_Clear();
1489 }
1490#endif
1491
Tim Peters5aa91602002-01-30 05:46:57 +00001492 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001493 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001494 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001495 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001496
Barry Warsaw53699e91996-12-10 23:23:01 +00001497 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001498 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001499 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001500
1501 if (res != 0) {
1502#ifdef MS_WINDOWS
1503 result = win32_error("stat", pathfree);
1504#else
1505 result = posix_error_with_filename(pathfree);
1506#endif
1507 }
1508 else
1509 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001510
Tim Peters500bd032001-12-19 19:05:01 +00001511 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001512 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001513}
1514
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001515/* POSIX methods */
1516
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001517PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001518"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001519Use the real uid/gid to test for access to a path. Note that most\n\
1520operations will use the effective uid/gid, therefore this routine can\n\
1521be used in a suid/sgid environment to test if the invoking user has the\n\
1522specified access to the path. The mode argument can be F_OK to test\n\
1523existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001524
1525static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001526posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001527{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001528 char *path;
1529 int mode;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001530
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001531#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001532 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001533 if (unicode_file_names()) {
1534 PyUnicodeObject *po;
1535 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1536 Py_BEGIN_ALLOW_THREADS
1537 /* PyUnicode_AS_UNICODE OK without thread lock as
1538 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001539 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001540 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001541 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001542 }
1543 /* Drop the argument parsing error as narrow strings
1544 are also valid. */
1545 PyErr_Clear();
1546 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001547 if (!PyArg_ParseTuple(args, "eti:access",
1548 Py_FileSystemDefaultEncoding, &path, &mode))
1549 return 0;
1550 Py_BEGIN_ALLOW_THREADS
1551 attr = GetFileAttributesA(path);
1552 Py_END_ALLOW_THREADS
1553 PyMem_Free(path);
1554finish:
1555 if (attr == 0xFFFFFFFF)
1556 /* File does not exist, or cannot read attributes */
1557 return PyBool_FromLong(0);
1558 /* Access is possible if either write access wasn't requested, or
Martin v. Löwis7b3cc062007-12-03 23:09:04 +00001559 the file isn't read-only, or if it's a directory, as there are
1560 no read-only directories on Windows. */
1561 return PyBool_FromLong(!(mode & 2)
1562 || !(attr & FILE_ATTRIBUTE_READONLY)
1563 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001564#else
1565 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001566 if (!PyArg_ParseTuple(args, "eti:access",
1567 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001568 return NULL;
1569 Py_BEGIN_ALLOW_THREADS
1570 res = access(path, mode);
1571 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001572 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001573 return PyBool_FromLong(res == 0);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001574#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001575}
1576
Guido van Rossumd371ff11999-01-25 16:12:23 +00001577#ifndef F_OK
1578#define F_OK 0
1579#endif
1580#ifndef R_OK
1581#define R_OK 4
1582#endif
1583#ifndef W_OK
1584#define W_OK 2
1585#endif
1586#ifndef X_OK
1587#define X_OK 1
1588#endif
1589
1590#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001591PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001592"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001593Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001594
1595static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001596posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001597{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001598 int id;
1599 char *ret;
1600
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001601 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001602 return NULL;
1603
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001604#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001605 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001606 if (id == 0) {
1607 ret = ttyname();
1608 }
1609 else {
1610 ret = NULL;
1611 }
1612#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001613 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001614#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001615 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001616 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001617 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001618}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001619#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001620
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001621#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001622PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001623"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001624Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001625
1626static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001627posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001628{
1629 char *ret;
1630 char buffer[L_ctermid];
1631
Greg Wardb48bc172000-03-01 21:51:56 +00001632#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001633 ret = ctermid_r(buffer);
1634#else
1635 ret = ctermid(buffer);
1636#endif
1637 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001638 return posix_error();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00001639 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001640}
1641#endif
1642
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001643PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001644"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001645Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001646
Barry Warsaw53699e91996-12-10 23:23:01 +00001647static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001648posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001649{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001650#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001651 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001652#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001653 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001654#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001655 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001656#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001657 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001658#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001659}
1660
Fred Drake4d1e64b2002-04-15 19:40:07 +00001661#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001662PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001663"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001664Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001665opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001666
1667static PyObject *
1668posix_fchdir(PyObject *self, PyObject *fdobj)
1669{
1670 return posix_fildes(fdobj, fchdir);
1671}
1672#endif /* HAVE_FCHDIR */
1673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001674
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001675PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001676"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001677Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001678
Barry Warsaw53699e91996-12-10 23:23:01 +00001679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001680posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001681{
Mark Hammondef8b6542001-05-13 08:04:26 +00001682 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001683 int i;
1684 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001685#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001686 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001687 if (unicode_file_names()) {
1688 PyUnicodeObject *po;
1689 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1690 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001691 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1692 if (attr != 0xFFFFFFFF) {
1693 if (i & _S_IWRITE)
1694 attr &= ~FILE_ATTRIBUTE_READONLY;
1695 else
1696 attr |= FILE_ATTRIBUTE_READONLY;
1697 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1698 }
1699 else
1700 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001701 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001702 if (!res)
1703 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001704 PyUnicode_AS_UNICODE(po));
1705 Py_INCREF(Py_None);
1706 return Py_None;
1707 }
1708 /* Drop the argument parsing error as narrow strings
1709 are also valid. */
1710 PyErr_Clear();
1711 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001712 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1713 &path, &i))
1714 return NULL;
1715 Py_BEGIN_ALLOW_THREADS
1716 attr = GetFileAttributesA(path);
1717 if (attr != 0xFFFFFFFF) {
1718 if (i & _S_IWRITE)
1719 attr &= ~FILE_ATTRIBUTE_READONLY;
1720 else
1721 attr |= FILE_ATTRIBUTE_READONLY;
1722 res = SetFileAttributesA(path, attr);
1723 }
1724 else
1725 res = 0;
1726 Py_END_ALLOW_THREADS
1727 if (!res) {
1728 win32_error("chmod", path);
1729 PyMem_Free(path);
1730 return NULL;
1731 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001732 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001733 Py_INCREF(Py_None);
1734 return Py_None;
1735#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001736 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001737 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001738 return NULL;
1739 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001740 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001741 Py_END_ALLOW_THREADS
1742 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001743 return posix_error_with_allocated_filename(path);
1744 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001745 Py_INCREF(Py_None);
1746 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001747#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001748}
1749
Christian Heimes36281872007-11-30 21:11:28 +00001750#ifdef HAVE_FCHMOD
1751PyDoc_STRVAR(posix_fchmod__doc__,
1752"fchmod(fd, mode)\n\n\
1753Change the access permissions of the file given by file\n\
1754descriptor fd.");
1755
1756static PyObject *
1757posix_fchmod(PyObject *self, PyObject *args)
1758{
1759 int fd, mode, res;
1760 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1761 return NULL;
1762 Py_BEGIN_ALLOW_THREADS
1763 res = fchmod(fd, mode);
1764 Py_END_ALLOW_THREADS
1765 if (res < 0)
1766 return posix_error();
1767 Py_RETURN_NONE;
1768}
1769#endif /* HAVE_FCHMOD */
1770
1771#ifdef HAVE_LCHMOD
1772PyDoc_STRVAR(posix_lchmod__doc__,
1773"lchmod(path, mode)\n\n\
1774Change the access permissions of a file. If path is a symlink, this\n\
1775affects the link itself rather than the target.");
1776
1777static PyObject *
1778posix_lchmod(PyObject *self, PyObject *args)
1779{
1780 char *path = NULL;
1781 int i;
1782 int res;
1783 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1784 &path, &i))
1785 return NULL;
1786 Py_BEGIN_ALLOW_THREADS
1787 res = lchmod(path, i);
1788 Py_END_ALLOW_THREADS
1789 if (res < 0)
1790 return posix_error_with_allocated_filename(path);
1791 PyMem_Free(path);
1792 Py_RETURN_NONE;
1793}
1794#endif /* HAVE_LCHMOD */
1795
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001796
Martin v. Löwis382abef2007-02-19 10:55:19 +00001797#ifdef HAVE_CHFLAGS
1798PyDoc_STRVAR(posix_chflags__doc__,
1799"chflags(path, flags)\n\n\
1800Set file flags.");
1801
1802static PyObject *
1803posix_chflags(PyObject *self, PyObject *args)
1804{
1805 char *path;
1806 unsigned long flags;
1807 int res;
1808 if (!PyArg_ParseTuple(args, "etk:chflags",
1809 Py_FileSystemDefaultEncoding, &path, &flags))
1810 return NULL;
1811 Py_BEGIN_ALLOW_THREADS
1812 res = chflags(path, flags);
1813 Py_END_ALLOW_THREADS
1814 if (res < 0)
1815 return posix_error_with_allocated_filename(path);
1816 PyMem_Free(path);
1817 Py_INCREF(Py_None);
1818 return Py_None;
1819}
1820#endif /* HAVE_CHFLAGS */
1821
1822#ifdef HAVE_LCHFLAGS
1823PyDoc_STRVAR(posix_lchflags__doc__,
1824"lchflags(path, flags)\n\n\
1825Set file flags.\n\
1826This function will not follow symbolic links.");
1827
1828static PyObject *
1829posix_lchflags(PyObject *self, PyObject *args)
1830{
1831 char *path;
1832 unsigned long flags;
1833 int res;
1834 if (!PyArg_ParseTuple(args, "etk:lchflags",
1835 Py_FileSystemDefaultEncoding, &path, &flags))
1836 return NULL;
1837 Py_BEGIN_ALLOW_THREADS
1838 res = lchflags(path, flags);
1839 Py_END_ALLOW_THREADS
1840 if (res < 0)
1841 return posix_error_with_allocated_filename(path);
1842 PyMem_Free(path);
1843 Py_INCREF(Py_None);
1844 return Py_None;
1845}
1846#endif /* HAVE_LCHFLAGS */
1847
Martin v. Löwis244edc82001-10-04 22:44:26 +00001848#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001849PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001850"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001851Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001852
1853static PyObject *
1854posix_chroot(PyObject *self, PyObject *args)
1855{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001856 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001857}
1858#endif
1859
Guido van Rossum21142a01999-01-08 21:05:37 +00001860#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001861PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001862"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001863force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001864
1865static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001866posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001867{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001868 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001869}
1870#endif /* HAVE_FSYNC */
1871
1872#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001873
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001874#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001875extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1876#endif
1877
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001878PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001879"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001880force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001881 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001882
1883static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001884posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001885{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001886 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001887}
1888#endif /* HAVE_FDATASYNC */
1889
1890
Fredrik Lundh10723342000-07-10 16:38:09 +00001891#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001892PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001893"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001894Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001895
Barry Warsaw53699e91996-12-10 23:23:01 +00001896static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001897posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001898{
Mark Hammondef8b6542001-05-13 08:04:26 +00001899 char *path = NULL;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001900 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001901 int res;
Gregory P. Smithf48da8f2008-03-18 19:05:32 +00001902 if (!PyArg_ParseTuple(args, "etll:chown",
Tim Peters5aa91602002-01-30 05:46:57 +00001903 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001904 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001905 return NULL;
1906 Py_BEGIN_ALLOW_THREADS
1907 res = chown(path, (uid_t) uid, (gid_t) gid);
1908 Py_END_ALLOW_THREADS
1909 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001910 return posix_error_with_allocated_filename(path);
1911 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001912 Py_INCREF(Py_None);
1913 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001914}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001915#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001916
Christian Heimes36281872007-11-30 21:11:28 +00001917#ifdef HAVE_FCHOWN
1918PyDoc_STRVAR(posix_fchown__doc__,
1919"fchown(fd, uid, gid)\n\n\
1920Change the owner and group id of the file given by file descriptor\n\
1921fd to the numeric uid and gid.");
1922
1923static PyObject *
1924posix_fchown(PyObject *self, PyObject *args)
1925{
1926 int fd, uid, gid;
1927 int res;
1928 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
1929 return NULL;
1930 Py_BEGIN_ALLOW_THREADS
1931 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1932 Py_END_ALLOW_THREADS
1933 if (res < 0)
1934 return posix_error();
1935 Py_RETURN_NONE;
1936}
1937#endif /* HAVE_FCHOWN */
1938
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001939#ifdef HAVE_LCHOWN
1940PyDoc_STRVAR(posix_lchown__doc__,
1941"lchown(path, uid, gid)\n\n\
1942Change the owner and group id of path to the numeric uid and gid.\n\
1943This function will not follow symbolic links.");
1944
1945static PyObject *
1946posix_lchown(PyObject *self, PyObject *args)
1947{
1948 char *path = NULL;
1949 int uid, gid;
1950 int res;
1951 if (!PyArg_ParseTuple(args, "etii:lchown",
1952 Py_FileSystemDefaultEncoding, &path,
1953 &uid, &gid))
1954 return NULL;
1955 Py_BEGIN_ALLOW_THREADS
1956 res = lchown(path, (uid_t) uid, (gid_t) gid);
1957 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001958 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001959 return posix_error_with_allocated_filename(path);
1960 PyMem_Free(path);
1961 Py_INCREF(Py_None);
1962 return Py_None;
1963}
1964#endif /* HAVE_LCHOWN */
1965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001966
Guido van Rossum36bc6801995-06-14 22:54:23 +00001967#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001968PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001969"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001970Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001971
Barry Warsaw53699e91996-12-10 23:23:01 +00001972static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001973posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001974{
Facundo Batista5596b0c2008-06-22 13:36:20 +00001975 int bufsize_incr = 1024;
1976 int bufsize = 0;
1977 char *tmpbuf = NULL;
1978 char *res = NULL;
1979 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00001980
Barry Warsaw53699e91996-12-10 23:23:01 +00001981 Py_BEGIN_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00001982 do {
1983 bufsize = bufsize + bufsize_incr;
1984 tmpbuf = malloc(bufsize);
1985 if (tmpbuf == NULL) {
1986 break;
1987 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001988#if defined(PYOS_OS2) && defined(PYCC_GCC)
Facundo Batista5596b0c2008-06-22 13:36:20 +00001989 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001990#else
Facundo Batista5596b0c2008-06-22 13:36:20 +00001991 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001992#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00001993
1994 if (res == NULL) {
1995 free(tmpbuf);
1996 }
1997 } while ((res == NULL) && (errno == ERANGE));
Barry Warsaw53699e91996-12-10 23:23:01 +00001998 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00001999
Guido van Rossumff4949e1992-08-05 19:58:53 +00002000 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002001 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002002
2003 dynamic_return = PyString_FromString(tmpbuf);
2004 free(tmpbuf);
2005
2006 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002007}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002008
Walter Dörwald3b918c32002-11-21 20:18:46 +00002009#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002010PyDoc_STRVAR(posix_getcwdu__doc__,
2011"getcwdu() -> path\n\n\
2012Return a unicode string representing the current working directory.");
2013
2014static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002015posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002016{
2017 char buf[1026];
2018 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002019
2020#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002021 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002022 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002023 wchar_t wbuf[1026];
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002024 wchar_t *wbuf2 = wbuf;
2025 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002026 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002027 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2028 /* If the buffer is large enough, len does not include the
2029 terminating \0. If the buffer is too small, len includes
2030 the space needed for the terminator. */
2031 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2032 wbuf2 = malloc(len * sizeof(wchar_t));
2033 if (wbuf2)
2034 len = GetCurrentDirectoryW(len, wbuf2);
2035 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002036 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002037 if (!wbuf2) {
2038 PyErr_NoMemory();
2039 return NULL;
2040 }
2041 if (!len) {
2042 if (wbuf2 != wbuf) free(wbuf2);
2043 return win32_error("getcwdu", NULL);
2044 }
2045 resobj = PyUnicode_FromWideChar(wbuf2, len);
2046 if (wbuf2 != wbuf) free(wbuf2);
2047 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002048 }
2049#endif
2050
2051 Py_BEGIN_ALLOW_THREADS
2052#if defined(PYOS_OS2) && defined(PYCC_GCC)
2053 res = _getcwd2(buf, sizeof buf);
2054#else
2055 res = getcwd(buf, sizeof buf);
2056#endif
2057 Py_END_ALLOW_THREADS
2058 if (res == NULL)
2059 return posix_error();
2060 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2061}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002062#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00002063#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002064
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002065
Guido van Rossumb6775db1994-08-01 11:34:53 +00002066#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002067PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002068"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002069Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002070
Barry Warsaw53699e91996-12-10 23:23:01 +00002071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002072posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002073{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002074 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002075}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002076#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002077
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002078
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002079PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002080"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002081Return a list containing the names of the entries in the directory.\n\
2082\n\
2083 path: path of directory to list\n\
2084\n\
2085The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002086entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002087
Barry Warsaw53699e91996-12-10 23:23:01 +00002088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002089posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002090{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002091 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002092 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002093#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002094
Barry Warsaw53699e91996-12-10 23:23:01 +00002095 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002096 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002097 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002098 WIN32_FIND_DATA FileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002099 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002100 char *bufptr = namebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002101 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002102
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002103#ifdef Py_WIN_WIDE_FILENAMES
2104 /* If on wide-character-capable OS see if argument
2105 is Unicode and if so use wide API. */
2106 if (unicode_file_names()) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002107 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002108 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2109 WIN32_FIND_DATAW wFileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002110 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002111 Py_UNICODE wch;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002112 /* Overallocate for \\*.*\0 */
2113 len = PyUnicode_GET_SIZE(po);
2114 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2115 if (!wnamebuf) {
2116 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002117 return NULL;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002118 }
2119 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2120 wch = len > 0 ? wnamebuf[len-1] : '\0';
2121 if (wch != L'/' && wch != L'\\' && wch != L':')
2122 wnamebuf[len++] = L'\\';
2123 wcscpy(wnamebuf + len, L"*.*");
2124 if ((d = PyList_New(0)) == NULL) {
2125 free(wnamebuf);
2126 return NULL;
2127 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002128 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2129 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002130 int error = GetLastError();
2131 if (error == ERROR_FILE_NOT_FOUND) {
2132 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002133 return d;
2134 }
2135 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002136 win32_error_unicode("FindFirstFileW", wnamebuf);
2137 free(wnamebuf);
2138 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002139 }
2140 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002141 /* Skip over . and .. */
2142 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2143 wcscmp(wFileData.cFileName, L"..") != 0) {
2144 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2145 if (v == NULL) {
2146 Py_DECREF(d);
2147 d = NULL;
2148 break;
2149 }
2150 if (PyList_Append(d, v) != 0) {
2151 Py_DECREF(v);
2152 Py_DECREF(d);
2153 d = NULL;
2154 break;
2155 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002156 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002157 }
Georg Brandl622927b2006-03-07 12:48:03 +00002158 Py_BEGIN_ALLOW_THREADS
2159 result = FindNextFileW(hFindFile, &wFileData);
2160 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002161 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2162 it got to the end of the directory. */
2163 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2164 Py_DECREF(d);
2165 win32_error_unicode("FindNextFileW", wnamebuf);
2166 FindClose(hFindFile);
2167 free(wnamebuf);
2168 return NULL;
2169 }
Georg Brandl622927b2006-03-07 12:48:03 +00002170 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002171
2172 if (FindClose(hFindFile) == FALSE) {
2173 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002174 win32_error_unicode("FindClose", wnamebuf);
2175 free(wnamebuf);
2176 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002177 }
Martin v. Löwise3edaea2006-05-15 05:51:36 +00002178 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002179 return d;
2180 }
2181 /* Drop the argument parsing error as narrow strings
2182 are also valid. */
2183 PyErr_Clear();
2184 }
2185#endif
2186
Tim Peters5aa91602002-01-30 05:46:57 +00002187 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002188 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002189 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002190 if (len > 0) {
2191 char ch = namebuf[len-1];
2192 if (ch != SEP && ch != ALTSEP && ch != ':')
2193 namebuf[len++] = '/';
2194 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002195 strcpy(namebuf + len, "*.*");
2196
Barry Warsaw53699e91996-12-10 23:23:01 +00002197 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002198 return NULL;
2199
2200 hFindFile = FindFirstFile(namebuf, &FileData);
2201 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002202 int error = GetLastError();
2203 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002204 return d;
2205 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002206 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002207 }
2208 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002209 /* Skip over . and .. */
2210 if (strcmp(FileData.cFileName, ".") != 0 &&
2211 strcmp(FileData.cFileName, "..") != 0) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002212 v = PyString_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002213 if (v == NULL) {
2214 Py_DECREF(d);
2215 d = NULL;
2216 break;
2217 }
2218 if (PyList_Append(d, v) != 0) {
2219 Py_DECREF(v);
2220 Py_DECREF(d);
2221 d = NULL;
2222 break;
2223 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002224 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002225 }
Georg Brandl622927b2006-03-07 12:48:03 +00002226 Py_BEGIN_ALLOW_THREADS
2227 result = FindNextFile(hFindFile, &FileData);
2228 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00002229 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2230 it got to the end of the directory. */
2231 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2232 Py_DECREF(d);
2233 win32_error("FindNextFile", namebuf);
2234 FindClose(hFindFile);
2235 return NULL;
2236 }
Georg Brandl622927b2006-03-07 12:48:03 +00002237 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002238
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002239 if (FindClose(hFindFile) == FALSE) {
2240 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002241 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002242 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002243
2244 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002245
Tim Peters0bb44a42000-09-15 07:44:49 +00002246#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002247
2248#ifndef MAX_PATH
2249#define MAX_PATH CCHMAXPATH
2250#endif
2251 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002252 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002253 PyObject *d, *v;
2254 char namebuf[MAX_PATH+5];
2255 HDIR hdir = 1;
2256 ULONG srchcnt = 1;
2257 FILEFINDBUF3 ep;
2258 APIRET rc;
2259
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002260 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002261 return NULL;
2262 if (len >= MAX_PATH) {
2263 PyErr_SetString(PyExc_ValueError, "path too long");
2264 return NULL;
2265 }
2266 strcpy(namebuf, name);
2267 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002268 if (*pt == ALTSEP)
2269 *pt = SEP;
2270 if (namebuf[len-1] != SEP)
2271 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002272 strcpy(namebuf + len, "*.*");
2273
2274 if ((d = PyList_New(0)) == NULL)
2275 return NULL;
2276
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002277 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2278 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002279 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002280 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2281 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2282 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002283
2284 if (rc != NO_ERROR) {
2285 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002286 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002287 }
2288
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002289 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002290 do {
2291 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002292 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002293 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002294
2295 strcpy(namebuf, ep.achName);
2296
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002297 /* Leave Case of Name Alone -- In Native Form */
2298 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002299
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002300 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002301 if (v == NULL) {
2302 Py_DECREF(d);
2303 d = NULL;
2304 break;
2305 }
2306 if (PyList_Append(d, v) != 0) {
2307 Py_DECREF(v);
2308 Py_DECREF(d);
2309 d = NULL;
2310 break;
2311 }
2312 Py_DECREF(v);
2313 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2314 }
2315
2316 return d;
2317#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002318
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002319 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002320 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002321 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002322 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002323 int arg_is_unicode = 1;
2324
Georg Brandl05e89b82006-04-11 07:04:06 +00002325 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002326 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2327 arg_is_unicode = 0;
2328 PyErr_Clear();
2329 }
2330 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002331 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002332 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002333 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002334 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002335 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002336 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002337 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002338 return NULL;
2339 }
Georg Brandl622927b2006-03-07 12:48:03 +00002340 for (;;) {
Georg Brandl86cbf812008-07-16 21:31:41 +00002341 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002342 Py_BEGIN_ALLOW_THREADS
2343 ep = readdir(dirp);
2344 Py_END_ALLOW_THREADS
Georg Brandl86cbf812008-07-16 21:31:41 +00002345 if (ep == NULL) {
2346 if (errno == 0) {
2347 break;
2348 } else {
2349 closedir(dirp);
2350 Py_DECREF(d);
2351 return posix_error_with_allocated_filename(name);
2352 }
2353 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002354 if (ep->d_name[0] == '.' &&
2355 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002356 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002357 continue;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002358 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002359 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002360 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002361 d = NULL;
2362 break;
2363 }
Just van Rossum46c97842003-02-25 21:42:15 +00002364#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002365 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002366 PyObject *w;
2367
2368 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002369 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002370 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002371 if (w != NULL) {
2372 Py_DECREF(v);
2373 v = w;
2374 }
2375 else {
2376 /* fall back to the original byte string, as
2377 discussed in patch #683592 */
2378 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002379 }
Just van Rossum46c97842003-02-25 21:42:15 +00002380 }
2381#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002382 if (PyList_Append(d, v) != 0) {
2383 Py_DECREF(v);
2384 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002385 d = NULL;
2386 break;
2387 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002388 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002389 }
2390 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002391 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002392
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002393 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002394
Tim Peters0bb44a42000-09-15 07:44:49 +00002395#endif /* which OS */
2396} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002397
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002398#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002399/* A helper function for abspath on win32 */
2400static PyObject *
2401posix__getfullpathname(PyObject *self, PyObject *args)
2402{
2403 /* assume encoded strings wont more than double no of chars */
2404 char inbuf[MAX_PATH*2];
2405 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002406 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002407 char outbuf[MAX_PATH*2];
2408 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002409#ifdef Py_WIN_WIDE_FILENAMES
2410 if (unicode_file_names()) {
2411 PyUnicodeObject *po;
2412 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
Georg Brandlbb608a82008-12-05 08:35:09 +00002413 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2414 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002415 Py_UNICODE *wtemp;
Georg Brandlbb608a82008-12-05 08:35:09 +00002416 DWORD result;
2417 PyObject *v;
2418 result = GetFullPathNameW(wpath,
2419 sizeof(woutbuf)/sizeof(woutbuf[0]),
2420 woutbuf, &wtemp);
2421 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2422 woutbufp = malloc(result * sizeof(Py_UNICODE));
2423 if (!woutbufp)
2424 return PyErr_NoMemory();
2425 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2426 }
2427 if (result)
2428 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2429 else
2430 v = win32_error_unicode("GetFullPathNameW", wpath);
2431 if (woutbufp != woutbuf)
2432 free(woutbufp);
2433 return v;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002434 }
2435 /* Drop the argument parsing error as narrow strings
2436 are also valid. */
2437 PyErr_Clear();
2438 }
2439#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002440 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2441 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002442 &insize))
2443 return NULL;
2444 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2445 outbuf, &temp))
2446 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002447 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2448 return PyUnicode_Decode(outbuf, strlen(outbuf),
2449 Py_FileSystemDefaultEncoding, NULL);
2450 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002451 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002452} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002453#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002454
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002455PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002456"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002457Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002458
Barry Warsaw53699e91996-12-10 23:23:01 +00002459static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002460posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002461{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002462 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002463 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002464 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002465
2466#ifdef Py_WIN_WIDE_FILENAMES
2467 if (unicode_file_names()) {
2468 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002469 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002470 Py_BEGIN_ALLOW_THREADS
2471 /* PyUnicode_AS_UNICODE OK without thread lock as
2472 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002473 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002474 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002475 if (!res)
2476 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002477 Py_INCREF(Py_None);
2478 return Py_None;
2479 }
2480 /* Drop the argument parsing error as narrow strings
2481 are also valid. */
2482 PyErr_Clear();
2483 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002484 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2485 Py_FileSystemDefaultEncoding, &path, &mode))
2486 return NULL;
2487 Py_BEGIN_ALLOW_THREADS
2488 /* PyUnicode_AS_UNICODE OK without thread lock as
2489 it is a simple dereference. */
2490 res = CreateDirectoryA(path, NULL);
2491 Py_END_ALLOW_THREADS
2492 if (!res) {
2493 win32_error("mkdir", path);
2494 PyMem_Free(path);
2495 return NULL;
2496 }
2497 PyMem_Free(path);
2498 Py_INCREF(Py_None);
2499 return Py_None;
2500#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002501
Tim Peters5aa91602002-01-30 05:46:57 +00002502 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002503 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002504 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002505 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002506#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002507 res = mkdir(path);
2508#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002509 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002510#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002511 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002512 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002513 return posix_error_with_allocated_filename(path);
2514 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002515 Py_INCREF(Py_None);
2516 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002517#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002518}
2519
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002520
Neal Norwitz1818ed72006-03-26 00:29:48 +00002521/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2522#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002523#include <sys/resource.h>
2524#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002525
Neal Norwitz1818ed72006-03-26 00:29:48 +00002526
2527#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002528PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002529"nice(inc) -> new_priority\n\n\
2530Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002531
Barry Warsaw53699e91996-12-10 23:23:01 +00002532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002533posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002534{
2535 int increment, value;
2536
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002537 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002538 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002539
2540 /* There are two flavours of 'nice': one that returns the new
2541 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002542 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2543 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002544
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002545 If we are of the nice family that returns the new priority, we
2546 need to clear errno before the call, and check if errno is filled
2547 before calling posix_error() on a returnvalue of -1, because the
2548 -1 may be the actual new priority! */
2549
2550 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002551 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002552#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002553 if (value == 0)
2554 value = getpriority(PRIO_PROCESS, 0);
2555#endif
2556 if (value == -1 && errno != 0)
2557 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002558 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002559 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002560}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002561#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002562
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002563PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002564"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002565Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002566
Barry Warsaw53699e91996-12-10 23:23:01 +00002567static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002568posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002569{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002570#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002571 PyObject *o1, *o2;
2572 char *p1, *p2;
2573 BOOL result;
2574 if (unicode_file_names()) {
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002575 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2576 goto error;
2577 if (!convert_to_unicode(&o1))
2578 goto error;
2579 if (!convert_to_unicode(&o2)) {
2580 Py_DECREF(o1);
2581 goto error;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002582 }
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +00002583 Py_BEGIN_ALLOW_THREADS
2584 result = MoveFileW(PyUnicode_AsUnicode(o1),
2585 PyUnicode_AsUnicode(o2));
2586 Py_END_ALLOW_THREADS
2587 Py_DECREF(o1);
2588 Py_DECREF(o2);
2589 if (!result)
2590 return win32_error("rename", NULL);
2591 Py_INCREF(Py_None);
2592 return Py_None;
2593error:
2594 PyErr_Clear();
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002595 }
2596 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2597 return NULL;
2598 Py_BEGIN_ALLOW_THREADS
2599 result = MoveFileA(p1, p2);
2600 Py_END_ALLOW_THREADS
2601 if (!result)
2602 return win32_error("rename", NULL);
2603 Py_INCREF(Py_None);
2604 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002605#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002606 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002607#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002608}
2609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002610
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002611PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002612"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002613Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002614
Barry Warsaw53699e91996-12-10 23:23:01 +00002615static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002616posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002617{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002618#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002619 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002620#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002621 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002622#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002623}
2624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002625
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002626PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002627"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002628Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002629
Barry Warsaw53699e91996-12-10 23:23:01 +00002630static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002631posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002632{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002633#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002634 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002635#else
2636 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2637#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002638}
2639
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002640
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002641#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002642PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002643"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002644Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002645
Barry Warsaw53699e91996-12-10 23:23:01 +00002646static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002647posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002648{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002649 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002650 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002651 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002652 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002653 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002654 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002655 Py_END_ALLOW_THREADS
2656 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002657}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002658#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002659
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002660
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002661PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002662"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002663Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002664
Barry Warsaw53699e91996-12-10 23:23:01 +00002665static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002666posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002667{
2668 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002669 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002670 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002671 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002672 if (i < 0)
2673 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002674 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002675}
2676
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002677
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002678PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002679"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002680Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002681
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002682PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002683"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002684Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002685
Barry Warsaw53699e91996-12-10 23:23:01 +00002686static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002687posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002688{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002689#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002690 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002691#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002692 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002693#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002694}
2695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002696
Guido van Rossumb6775db1994-08-01 11:34:53 +00002697#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002698PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002699"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002700Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002701
Barry Warsaw53699e91996-12-10 23:23:01 +00002702static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002703posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002704{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002705 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002706 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002707
Barry Warsaw53699e91996-12-10 23:23:01 +00002708 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002709 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002710 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002711 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002712 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002713 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002714 u.sysname,
2715 u.nodename,
2716 u.release,
2717 u.version,
2718 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002719}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002720#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002721
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002722static int
2723extract_time(PyObject *t, long* sec, long* usec)
2724{
2725 long intval;
2726 if (PyFloat_Check(t)) {
2727 double tval = PyFloat_AsDouble(t);
Christian Heimese93237d2007-12-19 02:37:44 +00002728 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002729 if (!intobj)
2730 return -1;
2731 intval = PyInt_AsLong(intobj);
2732 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002733 if (intval == -1 && PyErr_Occurred())
2734 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002735 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002736 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002737 if (*usec < 0)
2738 /* If rounding gave us a negative number,
2739 truncate. */
2740 *usec = 0;
2741 return 0;
2742 }
2743 intval = PyInt_AsLong(t);
2744 if (intval == -1 && PyErr_Occurred())
2745 return -1;
2746 *sec = intval;
2747 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002748 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002749}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002750
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002751PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002752"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002753utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002754Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002755second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002756
Barry Warsaw53699e91996-12-10 23:23:01 +00002757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002758posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002759{
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002760#ifdef Py_WIN_WIDE_FILENAMES
2761 PyObject *arg;
2762 PyUnicodeObject *obwpath;
2763 wchar_t *wpath = NULL;
2764 char *apath = NULL;
2765 HANDLE hFile;
2766 long atimesec, mtimesec, ausec, musec;
2767 FILETIME atime, mtime;
2768 PyObject *result = NULL;
2769
2770 if (unicode_file_names()) {
2771 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2772 wpath = PyUnicode_AS_UNICODE(obwpath);
2773 Py_BEGIN_ALLOW_THREADS
2774 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002775 NULL, OPEN_EXISTING,
2776 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002777 Py_END_ALLOW_THREADS
2778 if (hFile == INVALID_HANDLE_VALUE)
2779 return win32_error_unicode("utime", wpath);
2780 } else
2781 /* Drop the argument parsing error as narrow strings
2782 are also valid. */
2783 PyErr_Clear();
2784 }
2785 if (!wpath) {
2786 if (!PyArg_ParseTuple(args, "etO:utime",
2787 Py_FileSystemDefaultEncoding, &apath, &arg))
2788 return NULL;
2789 Py_BEGIN_ALLOW_THREADS
2790 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002791 NULL, OPEN_EXISTING,
2792 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002793 Py_END_ALLOW_THREADS
2794 if (hFile == INVALID_HANDLE_VALUE) {
2795 win32_error("utime", apath);
2796 PyMem_Free(apath);
2797 return NULL;
2798 }
2799 PyMem_Free(apath);
2800 }
2801
2802 if (arg == Py_None) {
2803 SYSTEMTIME now;
2804 GetSystemTime(&now);
2805 if (!SystemTimeToFileTime(&now, &mtime) ||
2806 !SystemTimeToFileTime(&now, &atime)) {
2807 win32_error("utime", NULL);
2808 goto done;
2809 }
2810 }
2811 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2812 PyErr_SetString(PyExc_TypeError,
2813 "utime() arg 2 must be a tuple (atime, mtime)");
2814 goto done;
2815 }
2816 else {
2817 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2818 &atimesec, &ausec) == -1)
2819 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002820 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002821 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2822 &mtimesec, &musec) == -1)
2823 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002824 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002825 }
2826 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2827 /* Avoid putting the file name into the error here,
2828 as that may confuse the user into believing that
2829 something is wrong with the file, when it also
2830 could be the time stamp that gives a problem. */
2831 win32_error("utime", NULL);
2832 }
2833 Py_INCREF(Py_None);
2834 result = Py_None;
2835done:
2836 CloseHandle(hFile);
2837 return result;
2838#else /* Py_WIN_WIDE_FILENAMES */
2839
Neal Norwitz2adf2102004-06-09 01:46:02 +00002840 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002841 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002842 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002843 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002844
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002845#if defined(HAVE_UTIMES)
2846 struct timeval buf[2];
2847#define ATIME buf[0].tv_sec
2848#define MTIME buf[1].tv_sec
2849#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002850/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002851 struct utimbuf buf;
2852#define ATIME buf.actime
2853#define MTIME buf.modtime
2854#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002855#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002856 time_t buf[2];
2857#define ATIME buf[0]
2858#define MTIME buf[1]
2859#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002860#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002861
Mark Hammond817c9292003-12-03 01:22:38 +00002862
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002863 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002864 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002865 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002866 if (arg == Py_None) {
2867 /* optional time values not given */
2868 Py_BEGIN_ALLOW_THREADS
2869 res = utime(path, NULL);
2870 Py_END_ALLOW_THREADS
2871 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002872 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002873 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002874 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002875 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002876 return NULL;
2877 }
2878 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002879 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002880 &atime, &ausec) == -1) {
2881 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002882 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002883 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002884 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002885 &mtime, &musec) == -1) {
2886 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002887 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002888 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002889 ATIME = atime;
2890 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002891#ifdef HAVE_UTIMES
2892 buf[0].tv_usec = ausec;
2893 buf[1].tv_usec = musec;
2894 Py_BEGIN_ALLOW_THREADS
2895 res = utimes(path, buf);
2896 Py_END_ALLOW_THREADS
2897#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002898 Py_BEGIN_ALLOW_THREADS
2899 res = utime(path, UTIME_ARG);
2900 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002901#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002902 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002903 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002904 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002905 }
Neal Norwitz96652712004-06-06 20:40:27 +00002906 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002907 Py_INCREF(Py_None);
2908 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002909#undef UTIME_ARG
2910#undef ATIME
2911#undef MTIME
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002912#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002913}
2914
Guido van Rossum85e3b011991-06-03 12:42:10 +00002915
Guido van Rossum3b066191991-06-04 19:40:25 +00002916/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002917
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002918PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002919"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002920Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002921
Barry Warsaw53699e91996-12-10 23:23:01 +00002922static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002923posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002924{
2925 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002926 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002927 return NULL;
2928 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002929 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002930}
2931
Martin v. Löwis114619e2002-10-07 06:44:21 +00002932#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2933static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002934free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002935{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002936 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002937 for (i = 0; i < count; i++)
2938 PyMem_Free(array[i]);
2939 PyMem_DEL(array);
2940}
2941#endif
2942
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002943
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002944#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002945PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002946"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002947Execute an executable path with arguments, replacing current process.\n\
2948\n\
2949 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002950 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002951
Barry Warsaw53699e91996-12-10 23:23:01 +00002952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002953posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002954{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002955 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002956 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002957 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002958 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002959 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002960
Guido van Rossum89b33251993-10-22 14:26:06 +00002961 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002962 argv is a list or tuple of strings. */
2963
Martin v. Löwis114619e2002-10-07 06:44:21 +00002964 if (!PyArg_ParseTuple(args, "etO:execv",
2965 Py_FileSystemDefaultEncoding,
2966 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002967 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002968 if (PyList_Check(argv)) {
2969 argc = PyList_Size(argv);
2970 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002971 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002972 else if (PyTuple_Check(argv)) {
2973 argc = PyTuple_Size(argv);
2974 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002975 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002976 else {
Fred Drake661ea262000-10-24 19:57:45 +00002977 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002978 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002979 return NULL;
2980 }
2981
Barry Warsaw53699e91996-12-10 23:23:01 +00002982 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002983 if (argvlist == NULL) {
2984 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002985 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002986 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002987 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002988 if (!PyArg_Parse((*getitem)(argv, i), "et",
2989 Py_FileSystemDefaultEncoding,
2990 &argvlist[i])) {
2991 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002992 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002993 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002994 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002995 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002996
Guido van Rossum85e3b011991-06-03 12:42:10 +00002997 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002998 }
2999 argvlist[argc] = NULL;
3000
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003001 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003002
Guido van Rossum85e3b011991-06-03 12:42:10 +00003003 /* If we get here it's definitely an error */
3004
Martin v. Löwis114619e2002-10-07 06:44:21 +00003005 free_string_array(argvlist, argc);
3006 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003007 return posix_error();
3008}
3009
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003010
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003011PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003012"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003013Execute a path with arguments and environment, replacing current process.\n\
3014\n\
3015 path: path of executable file\n\
3016 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003017 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003018
Barry Warsaw53699e91996-12-10 23:23:01 +00003019static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003020posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003021{
3022 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003023 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003024 char **argvlist;
3025 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003026 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003027 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003028 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003029 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003030
3031 /* execve has three arguments: (path, argv, env), where
3032 argv is a list or tuple of strings and env is a dictionary
3033 like posix.environ. */
3034
Martin v. Löwis114619e2002-10-07 06:44:21 +00003035 if (!PyArg_ParseTuple(args, "etOO:execve",
3036 Py_FileSystemDefaultEncoding,
3037 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003038 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003039 if (PyList_Check(argv)) {
3040 argc = PyList_Size(argv);
3041 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003042 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003043 else if (PyTuple_Check(argv)) {
3044 argc = PyTuple_Size(argv);
3045 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003046 }
3047 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003048 PyErr_SetString(PyExc_TypeError,
3049 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003050 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003051 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003052 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003053 PyErr_SetString(PyExc_TypeError,
3054 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003055 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003056 }
3057
Barry Warsaw53699e91996-12-10 23:23:01 +00003058 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003059 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003060 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003061 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003062 }
3063 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003064 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003065 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003066 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003067 &argvlist[i]))
3068 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003069 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003070 goto fail_1;
3071 }
3072 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003073 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003074 argvlist[argc] = NULL;
3075
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003076 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003077 if (i < 0)
3078 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003079 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003080 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003081 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003082 goto fail_1;
3083 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003084 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003085 keys = PyMapping_Keys(env);
3086 vals = PyMapping_Values(env);
3087 if (!keys || !vals)
3088 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003089 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3090 PyErr_SetString(PyExc_TypeError,
3091 "execve(): env.keys() or env.values() is not a list");
3092 goto fail_2;
3093 }
Tim Peters5aa91602002-01-30 05:46:57 +00003094
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003095 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003096 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003097 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003098
3099 key = PyList_GetItem(keys, pos);
3100 val = PyList_GetItem(vals, pos);
3101 if (!key || !val)
3102 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003103
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003104 if (!PyArg_Parse(
3105 key,
3106 "s;execve() arg 3 contains a non-string key",
3107 &k) ||
3108 !PyArg_Parse(
3109 val,
3110 "s;execve() arg 3 contains a non-string value",
3111 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003112 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003113 goto fail_2;
3114 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003115
3116#if defined(PYOS_OS2)
3117 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3118 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3119#endif
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003120 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003121 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003122 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003123 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003124 goto fail_2;
3125 }
Tim Petersc8996f52001-12-03 20:41:00 +00003126 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003127 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003128#if defined(PYOS_OS2)
3129 }
3130#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003131 }
3132 envlist[envc] = 0;
3133
3134 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003135
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003136 /* If we get here it's definitely an error */
3137
3138 (void) posix_error();
3139
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003140 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003141 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003142 PyMem_DEL(envlist[envc]);
3143 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003144 fail_1:
3145 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003146 Py_XDECREF(vals);
3147 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003148 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003149 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003150 return NULL;
3151}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003152#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003153
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003154
Guido van Rossuma1065681999-01-25 23:20:23 +00003155#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003156PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003157"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003158Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003159\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003160 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003161 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003162 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003163
3164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003165posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003166{
3167 char *path;
3168 PyObject *argv;
3169 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003170 int mode, i;
3171 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003172 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003173 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003174
3175 /* spawnv has three arguments: (mode, path, argv), where
3176 argv is a list or tuple of strings. */
3177
Martin v. Löwis114619e2002-10-07 06:44:21 +00003178 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3179 Py_FileSystemDefaultEncoding,
3180 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003181 return NULL;
3182 if (PyList_Check(argv)) {
3183 argc = PyList_Size(argv);
3184 getitem = PyList_GetItem;
3185 }
3186 else if (PyTuple_Check(argv)) {
3187 argc = PyTuple_Size(argv);
3188 getitem = PyTuple_GetItem;
3189 }
3190 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003191 PyErr_SetString(PyExc_TypeError,
3192 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003193 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003194 return NULL;
3195 }
3196
3197 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003198 if (argvlist == NULL) {
3199 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003200 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003201 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003202 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003203 if (!PyArg_Parse((*getitem)(argv, i), "et",
3204 Py_FileSystemDefaultEncoding,
3205 &argvlist[i])) {
3206 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003207 PyErr_SetString(
3208 PyExc_TypeError,
3209 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003210 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003211 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003212 }
3213 }
3214 argvlist[argc] = NULL;
3215
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003216#if defined(PYOS_OS2) && defined(PYCC_GCC)
3217 Py_BEGIN_ALLOW_THREADS
3218 spawnval = spawnv(mode, path, argvlist);
3219 Py_END_ALLOW_THREADS
3220#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003221 if (mode == _OLD_P_OVERLAY)
3222 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003223
Tim Peters25059d32001-12-07 20:35:43 +00003224 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003225 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003226 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003227#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003228
Martin v. Löwis114619e2002-10-07 06:44:21 +00003229 free_string_array(argvlist, argc);
3230 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003231
Fred Drake699f3522000-06-29 21:12:41 +00003232 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003233 return posix_error();
3234 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003235#if SIZEOF_LONG == SIZEOF_VOID_P
3236 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003237#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003238 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003239#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003240}
3241
3242
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003243PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003244"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003245Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003246\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003247 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003248 path: path of executable file\n\
3249 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003250 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003251
3252static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003253posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003254{
3255 char *path;
3256 PyObject *argv, *env;
3257 char **argvlist;
3258 char **envlist;
3259 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003260 int mode, pos, envc;
3261 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003262 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003263 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00003264 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003265
3266 /* spawnve has four arguments: (mode, path, argv, env), where
3267 argv is a list or tuple of strings and env is a dictionary
3268 like posix.environ. */
3269
Martin v. Löwis114619e2002-10-07 06:44:21 +00003270 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3271 Py_FileSystemDefaultEncoding,
3272 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003273 return NULL;
3274 if (PyList_Check(argv)) {
3275 argc = PyList_Size(argv);
3276 getitem = PyList_GetItem;
3277 }
3278 else if (PyTuple_Check(argv)) {
3279 argc = PyTuple_Size(argv);
3280 getitem = PyTuple_GetItem;
3281 }
3282 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003283 PyErr_SetString(PyExc_TypeError,
3284 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003285 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003286 }
3287 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003288 PyErr_SetString(PyExc_TypeError,
3289 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003290 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003291 }
3292
3293 argvlist = PyMem_NEW(char *, argc+1);
3294 if (argvlist == NULL) {
3295 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003296 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003297 }
3298 for (i = 0; i < argc; i++) {
3299 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003300 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003301 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003302 &argvlist[i]))
3303 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003304 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003305 goto fail_1;
3306 }
3307 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003308 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003309 argvlist[argc] = NULL;
3310
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003311 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003312 if (i < 0)
3313 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003314 envlist = PyMem_NEW(char *, i + 1);
3315 if (envlist == NULL) {
3316 PyErr_NoMemory();
3317 goto fail_1;
3318 }
3319 envc = 0;
3320 keys = PyMapping_Keys(env);
3321 vals = PyMapping_Values(env);
3322 if (!keys || !vals)
3323 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003324 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3325 PyErr_SetString(PyExc_TypeError,
3326 "spawnve(): env.keys() or env.values() is not a list");
3327 goto fail_2;
3328 }
Tim Peters5aa91602002-01-30 05:46:57 +00003329
Guido van Rossuma1065681999-01-25 23:20:23 +00003330 for (pos = 0; pos < i; pos++) {
3331 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003332 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003333
3334 key = PyList_GetItem(keys, pos);
3335 val = PyList_GetItem(vals, pos);
3336 if (!key || !val)
3337 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003338
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003339 if (!PyArg_Parse(
3340 key,
3341 "s;spawnve() arg 3 contains a non-string key",
3342 &k) ||
3343 !PyArg_Parse(
3344 val,
3345 "s;spawnve() arg 3 contains a non-string value",
3346 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003347 {
3348 goto fail_2;
3349 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003350 len = PyString_Size(key) + PyString_Size(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003351 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003352 if (p == NULL) {
3353 PyErr_NoMemory();
3354 goto fail_2;
3355 }
Tim Petersc8996f52001-12-03 20:41:00 +00003356 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003357 envlist[envc++] = p;
3358 }
3359 envlist[envc] = 0;
3360
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003361#if defined(PYOS_OS2) && defined(PYCC_GCC)
3362 Py_BEGIN_ALLOW_THREADS
3363 spawnval = spawnve(mode, path, argvlist, envlist);
3364 Py_END_ALLOW_THREADS
3365#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003366 if (mode == _OLD_P_OVERLAY)
3367 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003368
3369 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003370 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003371 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003372#endif
Tim Peters25059d32001-12-07 20:35:43 +00003373
Fred Drake699f3522000-06-29 21:12:41 +00003374 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003375 (void) posix_error();
3376 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003377#if SIZEOF_LONG == SIZEOF_VOID_P
3378 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003379#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003380 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003381#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003382
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003383 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003384 while (--envc >= 0)
3385 PyMem_DEL(envlist[envc]);
3386 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003387 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003388 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003389 Py_XDECREF(vals);
3390 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003391 fail_0:
3392 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003393 return res;
3394}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003395
3396/* OS/2 supports spawnvp & spawnvpe natively */
3397#if defined(PYOS_OS2)
3398PyDoc_STRVAR(posix_spawnvp__doc__,
3399"spawnvp(mode, file, args)\n\n\
3400Execute the program 'file' in a new process, using the environment\n\
3401search path to find the file.\n\
3402\n\
3403 mode: mode of process creation\n\
3404 file: executable file name\n\
3405 args: tuple or list of strings");
3406
3407static PyObject *
3408posix_spawnvp(PyObject *self, PyObject *args)
3409{
3410 char *path;
3411 PyObject *argv;
3412 char **argvlist;
3413 int mode, i, argc;
3414 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003415 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003416
3417 /* spawnvp has three arguments: (mode, path, argv), where
3418 argv is a list or tuple of strings. */
3419
3420 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3421 Py_FileSystemDefaultEncoding,
3422 &path, &argv))
3423 return NULL;
3424 if (PyList_Check(argv)) {
3425 argc = PyList_Size(argv);
3426 getitem = PyList_GetItem;
3427 }
3428 else if (PyTuple_Check(argv)) {
3429 argc = PyTuple_Size(argv);
3430 getitem = PyTuple_GetItem;
3431 }
3432 else {
3433 PyErr_SetString(PyExc_TypeError,
3434 "spawnvp() arg 2 must be a tuple or list");
3435 PyMem_Free(path);
3436 return NULL;
3437 }
3438
3439 argvlist = PyMem_NEW(char *, argc+1);
3440 if (argvlist == NULL) {
3441 PyMem_Free(path);
3442 return PyErr_NoMemory();
3443 }
3444 for (i = 0; i < argc; i++) {
3445 if (!PyArg_Parse((*getitem)(argv, i), "et",
3446 Py_FileSystemDefaultEncoding,
3447 &argvlist[i])) {
3448 free_string_array(argvlist, i);
3449 PyErr_SetString(
3450 PyExc_TypeError,
3451 "spawnvp() arg 2 must contain only strings");
3452 PyMem_Free(path);
3453 return NULL;
3454 }
3455 }
3456 argvlist[argc] = NULL;
3457
3458 Py_BEGIN_ALLOW_THREADS
3459#if defined(PYCC_GCC)
3460 spawnval = spawnvp(mode, path, argvlist);
3461#else
3462 spawnval = _spawnvp(mode, path, argvlist);
3463#endif
3464 Py_END_ALLOW_THREADS
3465
3466 free_string_array(argvlist, argc);
3467 PyMem_Free(path);
3468
3469 if (spawnval == -1)
3470 return posix_error();
3471 else
3472 return Py_BuildValue("l", (long) spawnval);
3473}
3474
3475
3476PyDoc_STRVAR(posix_spawnvpe__doc__,
3477"spawnvpe(mode, file, args, env)\n\n\
3478Execute the program 'file' in a new process, using the environment\n\
3479search path to find the file.\n\
3480\n\
3481 mode: mode of process creation\n\
3482 file: executable file name\n\
3483 args: tuple or list of arguments\n\
3484 env: dictionary of strings mapping to strings");
3485
3486static PyObject *
3487posix_spawnvpe(PyObject *self, PyObject *args)
3488{
3489 char *path;
3490 PyObject *argv, *env;
3491 char **argvlist;
3492 char **envlist;
3493 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3494 int mode, i, pos, argc, envc;
3495 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003496 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003497 int lastarg = 0;
3498
3499 /* spawnvpe has four arguments: (mode, path, argv, env), where
3500 argv is a list or tuple of strings and env is a dictionary
3501 like posix.environ. */
3502
3503 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3504 Py_FileSystemDefaultEncoding,
3505 &path, &argv, &env))
3506 return NULL;
3507 if (PyList_Check(argv)) {
3508 argc = PyList_Size(argv);
3509 getitem = PyList_GetItem;
3510 }
3511 else if (PyTuple_Check(argv)) {
3512 argc = PyTuple_Size(argv);
3513 getitem = PyTuple_GetItem;
3514 }
3515 else {
3516 PyErr_SetString(PyExc_TypeError,
3517 "spawnvpe() arg 2 must be a tuple or list");
3518 goto fail_0;
3519 }
3520 if (!PyMapping_Check(env)) {
3521 PyErr_SetString(PyExc_TypeError,
3522 "spawnvpe() arg 3 must be a mapping object");
3523 goto fail_0;
3524 }
3525
3526 argvlist = PyMem_NEW(char *, argc+1);
3527 if (argvlist == NULL) {
3528 PyErr_NoMemory();
3529 goto fail_0;
3530 }
3531 for (i = 0; i < argc; i++) {
3532 if (!PyArg_Parse((*getitem)(argv, i),
3533 "et;spawnvpe() arg 2 must contain only strings",
3534 Py_FileSystemDefaultEncoding,
3535 &argvlist[i]))
3536 {
3537 lastarg = i;
3538 goto fail_1;
3539 }
3540 }
3541 lastarg = argc;
3542 argvlist[argc] = NULL;
3543
3544 i = PyMapping_Size(env);
3545 if (i < 0)
3546 goto fail_1;
3547 envlist = PyMem_NEW(char *, i + 1);
3548 if (envlist == NULL) {
3549 PyErr_NoMemory();
3550 goto fail_1;
3551 }
3552 envc = 0;
3553 keys = PyMapping_Keys(env);
3554 vals = PyMapping_Values(env);
3555 if (!keys || !vals)
3556 goto fail_2;
3557 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3558 PyErr_SetString(PyExc_TypeError,
3559 "spawnvpe(): env.keys() or env.values() is not a list");
3560 goto fail_2;
3561 }
3562
3563 for (pos = 0; pos < i; pos++) {
3564 char *p, *k, *v;
3565 size_t len;
3566
3567 key = PyList_GetItem(keys, pos);
3568 val = PyList_GetItem(vals, pos);
3569 if (!key || !val)
3570 goto fail_2;
3571
3572 if (!PyArg_Parse(
3573 key,
3574 "s;spawnvpe() arg 3 contains a non-string key",
3575 &k) ||
3576 !PyArg_Parse(
3577 val,
3578 "s;spawnvpe() arg 3 contains a non-string value",
3579 &v))
3580 {
3581 goto fail_2;
3582 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003583 len = PyString_Size(key) + PyString_Size(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003584 p = PyMem_NEW(char, len);
3585 if (p == NULL) {
3586 PyErr_NoMemory();
3587 goto fail_2;
3588 }
3589 PyOS_snprintf(p, len, "%s=%s", k, v);
3590 envlist[envc++] = p;
3591 }
3592 envlist[envc] = 0;
3593
3594 Py_BEGIN_ALLOW_THREADS
3595#if defined(PYCC_GCC)
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003596 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003597#else
Andrew MacIntyre94dcf0d2008-02-03 07:07:31 +00003598 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003599#endif
3600 Py_END_ALLOW_THREADS
3601
3602 if (spawnval == -1)
3603 (void) posix_error();
3604 else
3605 res = Py_BuildValue("l", (long) spawnval);
3606
3607 fail_2:
3608 while (--envc >= 0)
3609 PyMem_DEL(envlist[envc]);
3610 PyMem_DEL(envlist);
3611 fail_1:
3612 free_string_array(argvlist, lastarg);
3613 Py_XDECREF(vals);
3614 Py_XDECREF(keys);
3615 fail_0:
3616 PyMem_Free(path);
3617 return res;
3618}
3619#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003620#endif /* HAVE_SPAWNV */
3621
3622
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003623#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003624PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003625"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003626Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3627\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003628Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003629
3630static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003631posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003632{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003633 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003634 if (pid == -1)
3635 return posix_error();
Gregory P. Smithfb7a50f2008-07-14 06:06:48 +00003636 if (pid == 0)
3637 PyOS_AfterFork();
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00003638 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003639}
3640#endif
3641
3642
Guido van Rossumad0ee831995-03-01 10:34:45 +00003643#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003644PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003645"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003646Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003647Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003648
Barry Warsaw53699e91996-12-10 23:23:01 +00003649static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003650posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003651{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003652 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003653 if (pid == -1)
3654 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003655 if (pid == 0)
3656 PyOS_AfterFork();
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00003657 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003658}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003659#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003660
Neal Norwitzb59798b2003-03-21 01:43:31 +00003661/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003662/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3663#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003664#define DEV_PTY_FILE "/dev/ptc"
3665#define HAVE_DEV_PTMX
3666#else
3667#define DEV_PTY_FILE "/dev/ptmx"
3668#endif
3669
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003670#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003671#ifdef HAVE_PTY_H
3672#include <pty.h>
3673#else
3674#ifdef HAVE_LIBUTIL_H
3675#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003676#endif /* HAVE_LIBUTIL_H */
3677#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003678#ifdef HAVE_STROPTS_H
3679#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003680#endif
3681#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003682
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003683#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003684PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003685"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003686Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003687
3688static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003689posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003690{
3691 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003692#ifndef HAVE_OPENPTY
3693 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003694#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003695#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003696 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003697#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003698 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003699#endif
3700#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003701
Thomas Wouters70c21a12000-07-14 14:28:33 +00003702#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003703 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3704 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003705#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003706 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3707 if (slave_name == NULL)
3708 return posix_error();
3709
3710 slave_fd = open(slave_name, O_RDWR);
3711 if (slave_fd < 0)
3712 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003713#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003714 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003715 if (master_fd < 0)
3716 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003717 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003718 /* change permission of slave */
3719 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003720 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003721 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003722 }
3723 /* unlock slave */
3724 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003725 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003726 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003727 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003728 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003729 slave_name = ptsname(master_fd); /* get name of slave */
3730 if (slave_name == NULL)
3731 return posix_error();
3732 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3733 if (slave_fd < 0)
3734 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003735#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003736 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3737 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003738#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003739 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003740#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003741#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003742#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003743
Fred Drake8cef4cf2000-06-28 16:40:38 +00003744 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003745
Fred Drake8cef4cf2000-06-28 16:40:38 +00003746}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003747#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003748
3749#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003750PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003751"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003752Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3753Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003754To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003755
3756static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003757posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003758{
Christian Heimes951cc0f2008-01-31 23:08:23 +00003759 int master_fd = -1;
3760 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003761
Fred Drake8cef4cf2000-06-28 16:40:38 +00003762 pid = forkpty(&master_fd, NULL, NULL, NULL);
3763 if (pid == -1)
3764 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003765 if (pid == 0)
3766 PyOS_AfterFork();
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00003767 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003768}
3769#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003770
Guido van Rossumad0ee831995-03-01 10:34:45 +00003771#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003772PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003773"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003774Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003775
Barry Warsaw53699e91996-12-10 23:23:01 +00003776static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003777posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003778{
Barry Warsaw53699e91996-12-10 23:23:01 +00003779 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003780}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003781#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003782
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003783
Guido van Rossumad0ee831995-03-01 10:34:45 +00003784#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003785PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003786"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003787Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003788
Barry Warsaw53699e91996-12-10 23:23:01 +00003789static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003790posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003791{
Barry Warsaw53699e91996-12-10 23:23:01 +00003792 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003793}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003794#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003795
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003796
Guido van Rossumad0ee831995-03-01 10:34:45 +00003797#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003798PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003799"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003800Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003801
Barry Warsaw53699e91996-12-10 23:23:01 +00003802static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003803posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003804{
Barry Warsaw53699e91996-12-10 23:23:01 +00003805 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003806}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003807#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003808
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003809
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003810PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003811"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003812Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003813
Barry Warsaw53699e91996-12-10 23:23:01 +00003814static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003815posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003816{
Antoine Pitroucd1376d2009-05-23 16:19:24 +00003817 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003818}
3819
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003820
Fred Drakec9680921999-12-13 16:37:25 +00003821#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003822PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003823"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003824Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003825
3826static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003827posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003828{
3829 PyObject *result = NULL;
3830
Fred Drakec9680921999-12-13 16:37:25 +00003831#ifdef NGROUPS_MAX
3832#define MAX_GROUPS NGROUPS_MAX
3833#else
3834 /* defined to be 16 on Solaris7, so this should be a small number */
3835#define MAX_GROUPS 64
3836#endif
3837 gid_t grouplist[MAX_GROUPS];
3838 int n;
3839
3840 n = getgroups(MAX_GROUPS, grouplist);
3841 if (n < 0)
3842 posix_error();
3843 else {
3844 result = PyList_New(n);
3845 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003846 int i;
3847 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003848 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003849 if (o == NULL) {
3850 Py_DECREF(result);
3851 result = NULL;
3852 break;
3853 }
3854 PyList_SET_ITEM(result, i, o);
3855 }
3856 }
3857 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003858
Fred Drakec9680921999-12-13 16:37:25 +00003859 return result;
3860}
3861#endif
3862
Martin v. Löwis606edc12002-06-13 21:09:11 +00003863#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003864PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003865"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003866Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003867
3868static PyObject *
3869posix_getpgid(PyObject *self, PyObject *args)
3870{
Antoine Pitroucd1376d2009-05-23 16:19:24 +00003871 pid_t pid, pgid;
3872 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
Martin v. Löwis606edc12002-06-13 21:09:11 +00003873 return NULL;
3874 pgid = getpgid(pid);
3875 if (pgid < 0)
3876 return posix_error();
Antoine Pitroucd1376d2009-05-23 16:19:24 +00003877 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00003878}
3879#endif /* HAVE_GETPGID */
3880
3881
Guido van Rossumb6775db1994-08-01 11:34:53 +00003882#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003883PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003884"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003885Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003886
Barry Warsaw53699e91996-12-10 23:23:01 +00003887static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003888posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003889{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003890#ifdef GETPGRP_HAVE_ARG
Antoine Pitroucd1376d2009-05-23 16:19:24 +00003891 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003892#else /* GETPGRP_HAVE_ARG */
Antoine Pitroucd1376d2009-05-23 16:19:24 +00003893 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003894#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003895}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003896#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003898
Guido van Rossumb6775db1994-08-01 11:34:53 +00003899#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003900PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003901"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003902Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003903
Barry Warsaw53699e91996-12-10 23:23:01 +00003904static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003905posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003906{
Guido van Rossum64933891994-10-20 21:56:42 +00003907#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003908 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003909#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003910 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003911#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003912 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003913 Py_INCREF(Py_None);
3914 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003915}
3916
Guido van Rossumb6775db1994-08-01 11:34:53 +00003917#endif /* HAVE_SETPGRP */
3918
Guido van Rossumad0ee831995-03-01 10:34:45 +00003919#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003920PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003921"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003922Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003923
Barry Warsaw53699e91996-12-10 23:23:01 +00003924static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003925posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003926{
Antoine Pitroucd1376d2009-05-23 16:19:24 +00003927 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003928}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003929#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003930
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003931
Fred Drake12c6e2d1999-12-14 21:25:03 +00003932#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003933PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003934"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003935Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003936
3937static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003938posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003939{
Neal Norwitze241ce82003-02-17 18:17:05 +00003940 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003941 char *name;
3942 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003943
Fred Drakea30680b2000-12-06 21:24:28 +00003944 errno = 0;
3945 name = getlogin();
3946 if (name == NULL) {
3947 if (errno)
3948 posix_error();
3949 else
3950 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003951 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003952 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003953 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00003954 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003955 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003956
Fred Drake12c6e2d1999-12-14 21:25:03 +00003957 return result;
3958}
3959#endif
3960
Guido van Rossumad0ee831995-03-01 10:34:45 +00003961#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003962PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003963"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003964Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003965
Barry Warsaw53699e91996-12-10 23:23:01 +00003966static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003967posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003968{
Barry Warsaw53699e91996-12-10 23:23:01 +00003969 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003970}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003971#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003972
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003973
Guido van Rossumad0ee831995-03-01 10:34:45 +00003974#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003975PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003976"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003977Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003978
Barry Warsaw53699e91996-12-10 23:23:01 +00003979static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003980posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003981{
Christian Heimesd491d712008-02-01 18:49:26 +00003982 pid_t pid;
3983 int sig;
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00003984 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003985 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003986#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003987 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3988 APIRET rc;
3989 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003990 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003991
3992 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3993 APIRET rc;
3994 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003995 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003996
3997 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003998 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003999#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00004000 if (kill(pid, sig) == -1)
4001 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004002#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004003 Py_INCREF(Py_None);
4004 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004005}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004006#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004007
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004008#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004009PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004010"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004011Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004012
4013static PyObject *
4014posix_killpg(PyObject *self, PyObject *args)
4015{
Antoine Pitroucd1376d2009-05-23 16:19:24 +00004016 int sig;
4017 pid_t pgid;
4018 /* XXX some man pages make the `pgid` parameter an int, others
4019 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4020 take the same type. Moreover, pid_t is always at least as wide as
4021 int (else compilation of this module fails), which is safe. */
4022 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004023 return NULL;
4024 if (killpg(pgid, sig) == -1)
4025 return posix_error();
4026 Py_INCREF(Py_None);
4027 return Py_None;
4028}
4029#endif
4030
Guido van Rossumc0125471996-06-28 18:55:32 +00004031#ifdef HAVE_PLOCK
4032
4033#ifdef HAVE_SYS_LOCK_H
4034#include <sys/lock.h>
4035#endif
4036
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004037PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004038"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004039Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004040
Barry Warsaw53699e91996-12-10 23:23:01 +00004041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004042posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004043{
4044 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004045 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004046 return NULL;
4047 if (plock(op) == -1)
4048 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004049 Py_INCREF(Py_None);
4050 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004051}
4052#endif
4053
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004054
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004055#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004056PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004057"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004058Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004059
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004060#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004061#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004062static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004063async_system(const char *command)
4064{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004065 char errormsg[256], args[1024];
4066 RESULTCODES rcodes;
4067 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004068
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004069 char *shell = getenv("COMSPEC");
4070 if (!shell)
4071 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004072
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004073 /* avoid overflowing the argument buffer */
4074 if (strlen(shell) + 3 + strlen(command) >= 1024)
4075 return ERROR_NOT_ENOUGH_MEMORY
4076
4077 args[0] = '\0';
4078 strcat(args, shell);
4079 strcat(args, "/c ");
4080 strcat(args, command);
4081
4082 /* execute asynchronously, inheriting the environment */
4083 rc = DosExecPgm(errormsg,
4084 sizeof(errormsg),
4085 EXEC_ASYNC,
4086 args,
4087 NULL,
4088 &rcodes,
4089 shell);
4090 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004091}
4092
Guido van Rossumd48f2521997-12-05 22:19:34 +00004093static FILE *
4094popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004095{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004096 int oldfd, tgtfd;
4097 HFILE pipeh[2];
4098 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004099
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004100 /* mode determines which of stdin or stdout is reconnected to
4101 * the pipe to the child
4102 */
4103 if (strchr(mode, 'r') != NULL) {
4104 tgt_fd = 1; /* stdout */
4105 } else if (strchr(mode, 'w')) {
4106 tgt_fd = 0; /* stdin */
4107 } else {
4108 *err = ERROR_INVALID_ACCESS;
4109 return NULL;
4110 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004111
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00004112 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004113 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4114 *err = rc;
4115 return NULL;
4116 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004117
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004118 /* prevent other threads accessing stdio */
4119 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004120
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004121 /* reconnect stdio and execute child */
4122 oldfd = dup(tgtfd);
4123 close(tgtfd);
4124 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4125 DosClose(pipeh[tgtfd]);
4126 rc = async_system(command);
4127 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004128
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004129 /* restore stdio */
4130 dup2(oldfd, tgtfd);
4131 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004132
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004133 /* allow other threads access to stdio */
4134 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004135
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004136 /* if execution of child was successful return file stream */
4137 if (rc == NO_ERROR)
4138 return fdopen(pipeh[1 - tgtfd], mode);
4139 else {
4140 DosClose(pipeh[1 - tgtfd]);
4141 *err = rc;
4142 return NULL;
4143 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004144}
4145
4146static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004147posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004148{
4149 char *name;
4150 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00004151 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004152 FILE *fp;
4153 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004154 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004155 return NULL;
4156 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00004157 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004158 Py_END_ALLOW_THREADS
4159 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004160 return os2_error(err);
4161
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004162 f = PyFile_FromFile(fp, name, mode, fclose);
4163 if (f != NULL)
4164 PyFile_SetBufSize(f, bufsize);
4165 return f;
4166}
4167
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004168#elif defined(PYCC_GCC)
4169
4170/* standard posix version of popen() support */
4171static PyObject *
4172posix_popen(PyObject *self, PyObject *args)
4173{
4174 char *name;
4175 char *mode = "r";
4176 int bufsize = -1;
4177 FILE *fp;
4178 PyObject *f;
4179 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4180 return NULL;
4181 Py_BEGIN_ALLOW_THREADS
4182 fp = popen(name, mode);
4183 Py_END_ALLOW_THREADS
4184 if (fp == NULL)
4185 return posix_error();
4186 f = PyFile_FromFile(fp, name, mode, pclose);
4187 if (f != NULL)
4188 PyFile_SetBufSize(f, bufsize);
4189 return f;
4190}
4191
4192/* fork() under OS/2 has lots'o'warts
4193 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4194 * most of this code is a ripoff of the win32 code, but using the
4195 * capabilities of EMX's C library routines
4196 */
4197
4198/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4199#define POPEN_1 1
4200#define POPEN_2 2
4201#define POPEN_3 3
4202#define POPEN_4 4
4203
4204static PyObject *_PyPopen(char *, int, int, int);
4205static int _PyPclose(FILE *file);
4206
4207/*
4208 * Internal dictionary mapping popen* file pointers to process handles,
4209 * for use when retrieving the process exit code. See _PyPclose() below
4210 * for more information on this dictionary's use.
4211 */
4212static PyObject *_PyPopenProcs = NULL;
4213
4214/* os2emx version of popen2()
4215 *
4216 * The result of this function is a pipe (file) connected to the
4217 * process's stdin, and a pipe connected to the process's stdout.
4218 */
4219
4220static PyObject *
4221os2emx_popen2(PyObject *self, PyObject *args)
4222{
4223 PyObject *f;
4224 int tm=0;
4225
4226 char *cmdstring;
4227 char *mode = "t";
4228 int bufsize = -1;
4229 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4230 return NULL;
4231
4232 if (*mode == 't')
4233 tm = O_TEXT;
4234 else if (*mode != 'b') {
4235 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4236 return NULL;
4237 } else
4238 tm = O_BINARY;
4239
4240 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4241
4242 return f;
4243}
4244
4245/*
4246 * Variation on os2emx.popen2
4247 *
4248 * The result of this function is 3 pipes - the process's stdin,
4249 * stdout and stderr
4250 */
4251
4252static PyObject *
4253os2emx_popen3(PyObject *self, PyObject *args)
4254{
4255 PyObject *f;
4256 int tm = 0;
4257
4258 char *cmdstring;
4259 char *mode = "t";
4260 int bufsize = -1;
4261 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4262 return NULL;
4263
4264 if (*mode == 't')
4265 tm = O_TEXT;
4266 else if (*mode != 'b') {
4267 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4268 return NULL;
4269 } else
4270 tm = O_BINARY;
4271
4272 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4273
4274 return f;
4275}
4276
4277/*
4278 * Variation on os2emx.popen2
4279 *
Tim Peters11b23062003-04-23 02:39:17 +00004280 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004281 * and stdout+stderr combined as a single pipe.
4282 */
4283
4284static PyObject *
4285os2emx_popen4(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:popen4", &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_4, bufsize);
4305
4306 return f;
4307}
4308
4309/* a couple of structures for convenient handling of multiple
4310 * file handles and pipes
4311 */
4312struct file_ref
4313{
4314 int handle;
4315 int flags;
4316};
4317
4318struct pipe_ref
4319{
4320 int rd;
4321 int wr;
4322};
4323
4324/* The following code is derived from the win32 code */
4325
4326static PyObject *
4327_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4328{
4329 struct file_ref stdio[3];
4330 struct pipe_ref p_fd[3];
4331 FILE *p_s[3];
Christian Heimesd491d712008-02-01 18:49:26 +00004332 int file_count, i, pipe_err;
4333 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004334 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4335 PyObject *f, *p_f[3];
4336
4337 /* file modes for subsequent fdopen's on pipe handles */
4338 if (mode == O_TEXT)
4339 {
4340 rd_mode = "rt";
4341 wr_mode = "wt";
4342 }
4343 else
4344 {
4345 rd_mode = "rb";
4346 wr_mode = "wb";
4347 }
4348
4349 /* prepare shell references */
4350 if ((shell = getenv("EMXSHELL")) == NULL)
4351 if ((shell = getenv("COMSPEC")) == NULL)
4352 {
4353 errno = ENOENT;
4354 return posix_error();
4355 }
4356
4357 sh_name = _getname(shell);
4358 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4359 opt = "/c";
4360 else
4361 opt = "-c";
4362
4363 /* save current stdio fds + their flags, and set not inheritable */
4364 i = pipe_err = 0;
4365 while (pipe_err >= 0 && i < 3)
4366 {
4367 pipe_err = stdio[i].handle = dup(i);
4368 stdio[i].flags = fcntl(i, F_GETFD, 0);
4369 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4370 i++;
4371 }
4372 if (pipe_err < 0)
4373 {
4374 /* didn't get them all saved - clean up and bail out */
4375 int saved_err = errno;
4376 while (i-- > 0)
4377 {
4378 close(stdio[i].handle);
4379 }
4380 errno = saved_err;
4381 return posix_error();
4382 }
4383
4384 /* create pipe ends */
4385 file_count = 2;
4386 if (n == POPEN_3)
4387 file_count = 3;
4388 i = pipe_err = 0;
4389 while ((pipe_err == 0) && (i < file_count))
4390 pipe_err = pipe((int *)&p_fd[i++]);
4391 if (pipe_err < 0)
4392 {
4393 /* didn't get them all made - clean up and bail out */
4394 while (i-- > 0)
4395 {
4396 close(p_fd[i].wr);
4397 close(p_fd[i].rd);
4398 }
4399 errno = EPIPE;
4400 return posix_error();
4401 }
4402
4403 /* change the actual standard IO streams over temporarily,
4404 * making the retained pipe ends non-inheritable
4405 */
4406 pipe_err = 0;
4407
4408 /* - stdin */
4409 if (dup2(p_fd[0].rd, 0) == 0)
4410 {
4411 close(p_fd[0].rd);
4412 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4413 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4414 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4415 {
4416 close(p_fd[0].wr);
4417 pipe_err = -1;
4418 }
4419 }
4420 else
4421 {
4422 pipe_err = -1;
4423 }
4424
4425 /* - stdout */
4426 if (pipe_err == 0)
4427 {
4428 if (dup2(p_fd[1].wr, 1) == 1)
4429 {
4430 close(p_fd[1].wr);
4431 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4432 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4433 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4434 {
4435 close(p_fd[1].rd);
4436 pipe_err = -1;
4437 }
4438 }
4439 else
4440 {
4441 pipe_err = -1;
4442 }
4443 }
4444
4445 /* - stderr, as required */
4446 if (pipe_err == 0)
4447 switch (n)
4448 {
4449 case POPEN_3:
4450 {
4451 if (dup2(p_fd[2].wr, 2) == 2)
4452 {
4453 close(p_fd[2].wr);
4454 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4455 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4456 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4457 {
4458 close(p_fd[2].rd);
4459 pipe_err = -1;
4460 }
4461 }
4462 else
4463 {
4464 pipe_err = -1;
4465 }
4466 break;
4467 }
4468
4469 case POPEN_4:
4470 {
4471 if (dup2(1, 2) != 2)
4472 {
4473 pipe_err = -1;
4474 }
4475 break;
4476 }
4477 }
4478
4479 /* spawn the child process */
4480 if (pipe_err == 0)
4481 {
4482 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4483 if (pipe_pid == -1)
4484 {
4485 pipe_err = -1;
4486 }
4487 else
4488 {
4489 /* save the PID into the FILE structure
4490 * NOTE: this implementation doesn't actually
4491 * take advantage of this, but do it for
4492 * completeness - AIM Apr01
4493 */
4494 for (i = 0; i < file_count; i++)
4495 p_s[i]->_pid = pipe_pid;
4496 }
4497 }
4498
4499 /* reset standard IO to normal */
4500 for (i = 0; i < 3; i++)
4501 {
4502 dup2(stdio[i].handle, i);
4503 fcntl(i, F_SETFD, stdio[i].flags);
4504 close(stdio[i].handle);
4505 }
4506
4507 /* if any remnant problems, clean up and bail out */
4508 if (pipe_err < 0)
4509 {
4510 for (i = 0; i < 3; i++)
4511 {
4512 close(p_fd[i].rd);
4513 close(p_fd[i].wr);
4514 }
4515 errno = EPIPE;
4516 return posix_error_with_filename(cmdstring);
4517 }
4518
4519 /* build tuple of file objects to return */
4520 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4521 PyFile_SetBufSize(p_f[0], bufsize);
4522 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4523 PyFile_SetBufSize(p_f[1], bufsize);
4524 if (n == POPEN_3)
4525 {
4526 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4527 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004528 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004529 }
4530 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004531 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004532
4533 /*
4534 * Insert the files we've created into the process dictionary
4535 * all referencing the list with the process handle and the
4536 * initial number of files (see description below in _PyPclose).
4537 * Since if _PyPclose later tried to wait on a process when all
4538 * handles weren't closed, it could create a deadlock with the
4539 * child, we spend some energy here to try to ensure that we
4540 * either insert all file handles into the dictionary or none
4541 * at all. It's a little clumsy with the various popen modes
4542 * and variable number of files involved.
4543 */
4544 if (!_PyPopenProcs)
4545 {
4546 _PyPopenProcs = PyDict_New();
4547 }
4548
4549 if (_PyPopenProcs)
4550 {
4551 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4552 int ins_rc[3];
4553
4554 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4555 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4556
4557 procObj = PyList_New(2);
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00004558 pidObj = PyLong_FromPid(pipe_pid);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004559 intObj = PyInt_FromLong((long) file_count);
4560
4561 if (procObj && pidObj && intObj)
4562 {
4563 PyList_SetItem(procObj, 0, pidObj);
4564 PyList_SetItem(procObj, 1, intObj);
4565
4566 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4567 if (fileObj[0])
4568 {
4569 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4570 fileObj[0],
4571 procObj);
4572 }
4573 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4574 if (fileObj[1])
4575 {
4576 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4577 fileObj[1],
4578 procObj);
4579 }
4580 if (file_count >= 3)
4581 {
4582 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4583 if (fileObj[2])
4584 {
4585 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4586 fileObj[2],
4587 procObj);
4588 }
4589 }
4590
4591 if (ins_rc[0] < 0 || !fileObj[0] ||
4592 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4593 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4594 {
4595 /* Something failed - remove any dictionary
4596 * entries that did make it.
4597 */
4598 if (!ins_rc[0] && fileObj[0])
4599 {
4600 PyDict_DelItem(_PyPopenProcs,
4601 fileObj[0]);
4602 }
4603 if (!ins_rc[1] && fileObj[1])
4604 {
4605 PyDict_DelItem(_PyPopenProcs,
4606 fileObj[1]);
4607 }
4608 if (!ins_rc[2] && fileObj[2])
4609 {
4610 PyDict_DelItem(_PyPopenProcs,
4611 fileObj[2]);
4612 }
4613 }
4614 }
Tim Peters11b23062003-04-23 02:39:17 +00004615
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004616 /*
4617 * Clean up our localized references for the dictionary keys
4618 * and value since PyDict_SetItem will Py_INCREF any copies
4619 * that got placed in the dictionary.
4620 */
4621 Py_XDECREF(procObj);
4622 Py_XDECREF(fileObj[0]);
4623 Py_XDECREF(fileObj[1]);
4624 Py_XDECREF(fileObj[2]);
4625 }
4626
4627 /* Child is launched. */
4628 return f;
4629}
4630
4631/*
4632 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4633 * exit code for the child process and return as a result of the close.
4634 *
4635 * This function uses the _PyPopenProcs dictionary in order to map the
4636 * input file pointer to information about the process that was
4637 * originally created by the popen* call that created the file pointer.
4638 * The dictionary uses the file pointer as a key (with one entry
4639 * inserted for each file returned by the original popen* call) and a
4640 * single list object as the value for all files from a single call.
4641 * The list object contains the Win32 process handle at [0], and a file
4642 * count at [1], which is initialized to the total number of file
4643 * handles using that list.
4644 *
4645 * This function closes whichever handle it is passed, and decrements
4646 * the file count in the dictionary for the process handle pointed to
4647 * by this file. On the last close (when the file count reaches zero),
4648 * this function will wait for the child process and then return its
4649 * exit code as the result of the close() operation. This permits the
4650 * files to be closed in any order - it is always the close() of the
4651 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004652 *
4653 * NOTE: This function is currently called with the GIL released.
4654 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004655 */
4656
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004657static int _PyPclose(FILE *file)
4658{
4659 int result;
4660 int exit_code;
Christian Heimesd491d712008-02-01 18:49:26 +00004661 pid_t pipe_pid;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004662 PyObject *procObj, *pidObj, *intObj, *fileObj;
4663 int file_count;
4664#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004665 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004666#endif
4667
4668 /* Close the file handle first, to ensure it can't block the
4669 * child from exiting if it's the last handle.
4670 */
4671 result = fclose(file);
4672
4673#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004674 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004675#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004676 if (_PyPopenProcs)
4677 {
4678 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4679 (procObj = PyDict_GetItem(_PyPopenProcs,
4680 fileObj)) != NULL &&
4681 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4682 (intObj = PyList_GetItem(procObj,1)) != NULL)
4683 {
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00004684 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004685 file_count = (int) PyInt_AsLong(intObj);
4686
4687 if (file_count > 1)
4688 {
4689 /* Still other files referencing process */
4690 file_count--;
4691 PyList_SetItem(procObj,1,
4692 PyInt_FromLong((long) file_count));
4693 }
4694 else
4695 {
4696 /* Last file for this process */
4697 if (result != EOF &&
4698 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4699 {
4700 /* extract exit status */
4701 if (WIFEXITED(exit_code))
4702 {
4703 result = WEXITSTATUS(exit_code);
4704 }
4705 else
4706 {
4707 errno = EPIPE;
4708 result = -1;
4709 }
4710 }
4711 else
4712 {
4713 /* Indicate failure - this will cause the file object
4714 * to raise an I/O error and translate the last
4715 * error code from errno. We do have a problem with
4716 * last errors that overlap the normal errno table,
4717 * but that's a consistent problem with the file object.
4718 */
4719 result = -1;
4720 }
4721 }
4722
4723 /* Remove this file pointer from dictionary */
4724 PyDict_DelItem(_PyPopenProcs, fileObj);
4725
4726 if (PyDict_Size(_PyPopenProcs) == 0)
4727 {
4728 Py_DECREF(_PyPopenProcs);
4729 _PyPopenProcs = NULL;
4730 }
4731
4732 } /* if object retrieval ok */
4733
4734 Py_XDECREF(fileObj);
4735 } /* if _PyPopenProcs */
4736
4737#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004738 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004739#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004740 return result;
4741}
4742
4743#endif /* PYCC_??? */
4744
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004745#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004746
4747/*
4748 * Portable 'popen' replacement for Win32.
4749 *
4750 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4751 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004752 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004753 */
4754
4755#include <malloc.h>
4756#include <io.h>
4757#include <fcntl.h>
4758
4759/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4760#define POPEN_1 1
4761#define POPEN_2 2
4762#define POPEN_3 3
4763#define POPEN_4 4
4764
4765static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004766static int _PyPclose(FILE *file);
4767
4768/*
4769 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004770 * for use when retrieving the process exit code. See _PyPclose() below
4771 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004772 */
4773static PyObject *_PyPopenProcs = NULL;
4774
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004775
4776/* popen that works from a GUI.
4777 *
4778 * The result of this function is a pipe (file) connected to the
4779 * processes stdin or stdout, depending on the requested mode.
4780 */
4781
4782static PyObject *
4783posix_popen(PyObject *self, PyObject *args)
4784{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004785 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004786 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004787
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004788 char *cmdstring;
4789 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004790 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004791 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004792 return NULL;
4793
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004794 if (*mode == 'r')
4795 tm = _O_RDONLY;
4796 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004797 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004798 return NULL;
4799 } else
4800 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004801
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004802 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004803 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004804 return NULL;
4805 }
4806
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004807 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004808 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004809 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004810 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004811 else
4812 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4813
4814 return f;
4815}
4816
4817/* Variation on win32pipe.popen
4818 *
4819 * The result of this function is a pipe (file) connected to the
4820 * process's stdin, and a pipe connected to the process's stdout.
4821 */
4822
4823static PyObject *
4824win32_popen2(PyObject *self, PyObject *args)
4825{
4826 PyObject *f;
4827 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004828
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004829 char *cmdstring;
4830 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004831 int bufsize = -1;
4832 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004833 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004834
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004835 if (*mode == 't')
4836 tm = _O_TEXT;
4837 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004838 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004839 return NULL;
4840 } else
4841 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004842
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004843 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004844 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004845 return NULL;
4846 }
4847
4848 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004849
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004850 return f;
4851}
4852
4853/*
4854 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004855 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004856 * The result of this function is 3 pipes - the process's stdin,
4857 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004858 */
4859
4860static PyObject *
4861win32_popen3(PyObject *self, PyObject *args)
4862{
4863 PyObject *f;
4864 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004865
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004866 char *cmdstring;
4867 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004868 int bufsize = -1;
4869 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004870 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004871
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004872 if (*mode == 't')
4873 tm = _O_TEXT;
4874 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004875 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004876 return NULL;
4877 } else
4878 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004879
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004880 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004881 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004882 return NULL;
4883 }
4884
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004885 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004886
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004887 return f;
4888}
4889
4890/*
4891 * Variation on win32pipe.popen
4892 *
Tim Peters5aa91602002-01-30 05:46:57 +00004893 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004894 * and stdout+stderr combined as a single pipe.
4895 */
4896
4897static PyObject *
4898win32_popen4(PyObject *self, PyObject *args)
4899{
4900 PyObject *f;
4901 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004902
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004903 char *cmdstring;
4904 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004905 int bufsize = -1;
4906 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004907 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004908
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004909 if (*mode == 't')
4910 tm = _O_TEXT;
4911 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004912 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004913 return NULL;
4914 } else
4915 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004916
4917 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004918 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004919 return NULL;
4920 }
4921
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004922 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004923
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004924 return f;
4925}
4926
Mark Hammond08501372001-01-31 07:30:29 +00004927static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004928_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004929 HANDLE hStdin,
4930 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004931 HANDLE hStderr,
4932 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004933{
4934 PROCESS_INFORMATION piProcInfo;
4935 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004936 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004937 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004938 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004939 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004940 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004941
4942 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004943 char *comshell;
4944
Tim Peters92e4dd82002-10-05 01:47:34 +00004945 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004946 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004947 /* x < i, so x fits into an integer */
4948 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004949
4950 /* Explicitly check if we are using COMMAND.COM. If we are
4951 * then use the w9xpopen hack.
4952 */
4953 comshell = s1 + x;
4954 while (comshell >= s1 && *comshell != '\\')
4955 --comshell;
4956 ++comshell;
4957
4958 if (GetVersion() < 0x80000000 &&
4959 _stricmp(comshell, "command.com") != 0) {
4960 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004961 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004962 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004963 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004964 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004965 }
4966 else {
4967 /*
Tim Peters402d5982001-08-27 06:37:48 +00004968 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4969 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004970 */
Mark Hammond08501372001-01-31 07:30:29 +00004971 char modulepath[_MAX_PATH];
4972 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004973 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00004974 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004975 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004976 x = i+1;
4977 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004978 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004979 strncat(modulepath,
4980 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004981 (sizeof(modulepath)/sizeof(modulepath[0]))
4982 -strlen(modulepath));
4983 if (stat(modulepath, &statinfo) != 0) {
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004984 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
Tim Peters5aa91602002-01-30 05:46:57 +00004985 /* Eeek - file-not-found - possibly an embedding
4986 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004987 */
Tim Peters5aa91602002-01-30 05:46:57 +00004988 strncpy(modulepath,
4989 Py_GetExecPrefix(),
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004990 mplen);
4991 modulepath[mplen-1] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004992 if (modulepath[strlen(modulepath)-1] != '\\')
4993 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004994 strncat(modulepath,
4995 szConsoleSpawn,
Kristján Valur Jónsson17b8e972007-04-25 00:10:50 +00004996 mplen-strlen(modulepath));
Mark Hammond08501372001-01-31 07:30:29 +00004997 /* No where else to look - raise an easily identifiable
4998 error, rather than leaving Windows to report
4999 "file not found" - as the user is probably blissfully
5000 unaware this shim EXE is used, and it will confuse them.
5001 (well, it confused me for a while ;-)
5002 */
5003 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00005004 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00005005 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00005006 "for popen to work with your shell "
5007 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00005008 szConsoleSpawn);
5009 return FALSE;
5010 }
5011 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005012 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00005013 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005014 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005015
Tim Peters92e4dd82002-10-05 01:47:34 +00005016 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005017 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005018 /* To maintain correct argument passing semantics,
5019 we pass the command-line as it stands, and allow
5020 quoting to be applied. w9xpopen.exe will then
5021 use its argv vector, and re-quote the necessary
5022 args for the ultimate child process.
5023 */
Tim Peters75cdad52001-11-28 22:07:30 +00005024 PyOS_snprintf(
5025 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00005026 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005027 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005028 s1,
5029 s3,
5030 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005031 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00005032 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005033 dialog:
5034 "Your program accessed mem currently in use at xxx"
5035 and a hopeful warning about the stability of your
5036 system.
5037 Cost is Ctrl+C wont kill children, but anyone
5038 who cares can have a go!
5039 */
5040 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005041 }
5042 }
5043
5044 /* Could be an else here to try cmd.exe / command.com in the path
5045 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00005046 else {
Tim Peters402d5982001-08-27 06:37:48 +00005047 PyErr_SetString(PyExc_RuntimeError,
5048 "Cannot locate a COMSPEC environment variable to "
5049 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00005050 return FALSE;
5051 }
Tim Peters5aa91602002-01-30 05:46:57 +00005052
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005053 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5054 siStartInfo.cb = sizeof(STARTUPINFO);
5055 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5056 siStartInfo.hStdInput = hStdin;
5057 siStartInfo.hStdOutput = hStdout;
5058 siStartInfo.hStdError = hStderr;
5059 siStartInfo.wShowWindow = SW_HIDE;
5060
5061 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005062 s2,
5063 NULL,
5064 NULL,
5065 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00005066 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005067 NULL,
5068 NULL,
5069 &siStartInfo,
5070 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005071 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005072 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005073
Mark Hammondb37a3732000-08-14 04:47:33 +00005074 /* Return process handle */
5075 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005076 return TRUE;
5077 }
Tim Peters402d5982001-08-27 06:37:48 +00005078 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005079 return FALSE;
5080}
5081
5082/* The following code is based off of KB: Q190351 */
5083
5084static PyObject *
5085_PyPopen(char *cmdstring, int mode, int n)
5086{
5087 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5088 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00005089 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005090
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005091 SECURITY_ATTRIBUTES saAttr;
5092 BOOL fSuccess;
5093 int fd1, fd2, fd3;
5094 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00005095 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005096 PyObject *f;
5097
5098 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5099 saAttr.bInheritHandle = TRUE;
5100 saAttr.lpSecurityDescriptor = NULL;
5101
5102 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5103 return win32_error("CreatePipe", NULL);
5104
5105 /* Create new output read handle and the input write handle. Set
5106 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00005107 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005108 * being created. */
5109 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005110 GetCurrentProcess(), &hChildStdinWrDup, 0,
5111 FALSE,
5112 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005113 if (!fSuccess)
5114 return win32_error("DuplicateHandle", NULL);
5115
5116 /* Close the inheritable version of ChildStdin
5117 that we're using. */
5118 CloseHandle(hChildStdinWr);
5119
5120 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5121 return win32_error("CreatePipe", NULL);
5122
5123 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005124 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5125 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005126 if (!fSuccess)
5127 return win32_error("DuplicateHandle", NULL);
5128
5129 /* Close the inheritable version of ChildStdout
5130 that we're using. */
5131 CloseHandle(hChildStdoutRd);
5132
5133 if (n != POPEN_4) {
5134 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5135 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005136 fSuccess = DuplicateHandle(GetCurrentProcess(),
5137 hChildStderrRd,
5138 GetCurrentProcess(),
5139 &hChildStderrRdDup, 0,
5140 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005141 if (!fSuccess)
5142 return win32_error("DuplicateHandle", NULL);
5143 /* Close the inheritable version of ChildStdErr that we're using. */
5144 CloseHandle(hChildStderrRd);
5145 }
Tim Peters5aa91602002-01-30 05:46:57 +00005146
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005147 switch (n) {
5148 case POPEN_1:
5149 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5150 case _O_WRONLY | _O_TEXT:
5151 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005152 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005153 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005154 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005155 PyFile_SetBufSize(f, 0);
5156 /* We don't care about these pipes anymore, so close them. */
5157 CloseHandle(hChildStdoutRdDup);
5158 CloseHandle(hChildStderrRdDup);
5159 break;
5160
5161 case _O_RDONLY | _O_TEXT:
5162 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005163 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005164 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005165 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005166 PyFile_SetBufSize(f, 0);
5167 /* We don't care about these pipes anymore, so close them. */
5168 CloseHandle(hChildStdinWrDup);
5169 CloseHandle(hChildStderrRdDup);
5170 break;
5171
5172 case _O_RDONLY | _O_BINARY:
5173 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005174 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005175 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005176 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005177 PyFile_SetBufSize(f, 0);
5178 /* We don't care about these pipes anymore, so close them. */
5179 CloseHandle(hChildStdinWrDup);
5180 CloseHandle(hChildStderrRdDup);
5181 break;
5182
5183 case _O_WRONLY | _O_BINARY:
5184 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005185 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005186 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005187 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005188 PyFile_SetBufSize(f, 0);
5189 /* We don't care about these pipes anymore, so close them. */
5190 CloseHandle(hChildStdoutRdDup);
5191 CloseHandle(hChildStderrRdDup);
5192 break;
5193 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005194 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005195 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005196
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005197 case POPEN_2:
5198 case POPEN_4:
5199 {
5200 char *m1, *m2;
5201 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005202
Tim Peters7dca21e2002-08-19 00:42:29 +00005203 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005204 m1 = "r";
5205 m2 = "w";
5206 } else {
5207 m1 = "rb";
5208 m2 = "wb";
5209 }
5210
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005211 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005212 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005213 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005214 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005215 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005216 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005217 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005218 PyFile_SetBufSize(p2, 0);
5219
5220 if (n != 4)
5221 CloseHandle(hChildStderrRdDup);
5222
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005223 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005224 Py_XDECREF(p1);
5225 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005226 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005227 break;
5228 }
Tim Peters5aa91602002-01-30 05:46:57 +00005229
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005230 case POPEN_3:
5231 {
5232 char *m1, *m2;
5233 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005234
Tim Peters7dca21e2002-08-19 00:42:29 +00005235 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005236 m1 = "r";
5237 m2 = "w";
5238 } else {
5239 m1 = "rb";
5240 m2 = "wb";
5241 }
5242
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005243 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005244 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005245 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005246 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005247 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005248 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005249 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005250 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5251 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005252 PyFile_SetBufSize(p1, 0);
5253 PyFile_SetBufSize(p2, 0);
5254 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005255 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005256 Py_XDECREF(p1);
5257 Py_XDECREF(p2);
5258 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005259 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005260 break;
5261 }
5262 }
5263
5264 if (n == POPEN_4) {
5265 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005266 hChildStdinRd,
5267 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005268 hChildStdoutWr,
5269 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005270 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005271 }
5272 else {
5273 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005274 hChildStdinRd,
5275 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005276 hChildStderrWr,
5277 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005278 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005279 }
5280
Mark Hammondb37a3732000-08-14 04:47:33 +00005281 /*
5282 * Insert the files we've created into the process dictionary
5283 * all referencing the list with the process handle and the
5284 * initial number of files (see description below in _PyPclose).
5285 * Since if _PyPclose later tried to wait on a process when all
5286 * handles weren't closed, it could create a deadlock with the
5287 * child, we spend some energy here to try to ensure that we
5288 * either insert all file handles into the dictionary or none
5289 * at all. It's a little clumsy with the various popen modes
5290 * and variable number of files involved.
5291 */
5292 if (!_PyPopenProcs) {
5293 _PyPopenProcs = PyDict_New();
5294 }
5295
5296 if (_PyPopenProcs) {
5297 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5298 int ins_rc[3];
5299
5300 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5301 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5302
5303 procObj = PyList_New(2);
5304 hProcessObj = PyLong_FromVoidPtr(hProcess);
5305 intObj = PyInt_FromLong(file_count);
5306
5307 if (procObj && hProcessObj && intObj) {
5308 PyList_SetItem(procObj,0,hProcessObj);
5309 PyList_SetItem(procObj,1,intObj);
5310
5311 fileObj[0] = PyLong_FromVoidPtr(f1);
5312 if (fileObj[0]) {
5313 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5314 fileObj[0],
5315 procObj);
5316 }
5317 if (file_count >= 2) {
5318 fileObj[1] = PyLong_FromVoidPtr(f2);
5319 if (fileObj[1]) {
5320 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5321 fileObj[1],
5322 procObj);
5323 }
5324 }
5325 if (file_count >= 3) {
5326 fileObj[2] = PyLong_FromVoidPtr(f3);
5327 if (fileObj[2]) {
5328 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5329 fileObj[2],
5330 procObj);
5331 }
5332 }
5333
5334 if (ins_rc[0] < 0 || !fileObj[0] ||
5335 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5336 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5337 /* Something failed - remove any dictionary
5338 * entries that did make it.
5339 */
5340 if (!ins_rc[0] && fileObj[0]) {
5341 PyDict_DelItem(_PyPopenProcs,
5342 fileObj[0]);
5343 }
5344 if (!ins_rc[1] && fileObj[1]) {
5345 PyDict_DelItem(_PyPopenProcs,
5346 fileObj[1]);
5347 }
5348 if (!ins_rc[2] && fileObj[2]) {
5349 PyDict_DelItem(_PyPopenProcs,
5350 fileObj[2]);
5351 }
5352 }
5353 }
Tim Peters5aa91602002-01-30 05:46:57 +00005354
Mark Hammondb37a3732000-08-14 04:47:33 +00005355 /*
5356 * Clean up our localized references for the dictionary keys
5357 * and value since PyDict_SetItem will Py_INCREF any copies
5358 * that got placed in the dictionary.
5359 */
5360 Py_XDECREF(procObj);
5361 Py_XDECREF(fileObj[0]);
5362 Py_XDECREF(fileObj[1]);
5363 Py_XDECREF(fileObj[2]);
5364 }
5365
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005366 /* Child is launched. Close the parents copy of those pipe
5367 * handles that only the child should have open. You need to
5368 * make sure that no handles to the write end of the output pipe
5369 * are maintained in this process or else the pipe will not close
5370 * when the child process exits and the ReadFile will hang. */
5371
5372 if (!CloseHandle(hChildStdinRd))
5373 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005374
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005375 if (!CloseHandle(hChildStdoutWr))
5376 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005377
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005378 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5379 return win32_error("CloseHandle", NULL);
5380
5381 return f;
5382}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005383
5384/*
5385 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5386 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005387 *
5388 * This function uses the _PyPopenProcs dictionary in order to map the
5389 * input file pointer to information about the process that was
5390 * originally created by the popen* call that created the file pointer.
5391 * The dictionary uses the file pointer as a key (with one entry
5392 * inserted for each file returned by the original popen* call) and a
5393 * single list object as the value for all files from a single call.
5394 * The list object contains the Win32 process handle at [0], and a file
5395 * count at [1], which is initialized to the total number of file
5396 * handles using that list.
5397 *
5398 * This function closes whichever handle it is passed, and decrements
5399 * the file count in the dictionary for the process handle pointed to
5400 * by this file. On the last close (when the file count reaches zero),
5401 * this function will wait for the child process and then return its
5402 * exit code as the result of the close() operation. This permits the
5403 * files to be closed in any order - it is always the close() of the
5404 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005405 *
5406 * NOTE: This function is currently called with the GIL released.
5407 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005408 */
Tim Peters736aa322000-09-01 06:51:24 +00005409
Fredrik Lundh56055a42000-07-23 19:47:12 +00005410static int _PyPclose(FILE *file)
5411{
Fredrik Lundh20318932000-07-26 17:29:12 +00005412 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005413 DWORD exit_code;
5414 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005415 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5416 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005417#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005418 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005419#endif
5420
Fredrik Lundh20318932000-07-26 17:29:12 +00005421 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005422 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005423 */
5424 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005425#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005426 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005427#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005428 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005429 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5430 (procObj = PyDict_GetItem(_PyPopenProcs,
5431 fileObj)) != NULL &&
5432 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5433 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5434
5435 hProcess = PyLong_AsVoidPtr(hProcessObj);
5436 file_count = PyInt_AsLong(intObj);
5437
5438 if (file_count > 1) {
5439 /* Still other files referencing process */
5440 file_count--;
5441 PyList_SetItem(procObj,1,
5442 PyInt_FromLong(file_count));
5443 } else {
5444 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005445 if (result != EOF &&
5446 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5447 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005448 /* Possible truncation here in 16-bit environments, but
5449 * real exit codes are just the lower byte in any event.
5450 */
5451 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005452 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005453 /* Indicate failure - this will cause the file object
5454 * to raise an I/O error and translate the last Win32
5455 * error code from errno. We do have a problem with
5456 * last errors that overlap the normal errno table,
5457 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005458 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005459 if (result != EOF) {
5460 /* If the error wasn't from the fclose(), then
5461 * set errno for the file object error handling.
5462 */
5463 errno = GetLastError();
5464 }
5465 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005466 }
5467
5468 /* Free up the native handle at this point */
5469 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005470 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005471
Mark Hammondb37a3732000-08-14 04:47:33 +00005472 /* Remove this file pointer from dictionary */
5473 PyDict_DelItem(_PyPopenProcs, fileObj);
5474
5475 if (PyDict_Size(_PyPopenProcs) == 0) {
5476 Py_DECREF(_PyPopenProcs);
5477 _PyPopenProcs = NULL;
5478 }
5479
5480 } /* if object retrieval ok */
5481
5482 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005483 } /* if _PyPopenProcs */
5484
Tim Peters736aa322000-09-01 06:51:24 +00005485#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005486 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005487#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005488 return result;
5489}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005490
5491#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005492static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005493posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005494{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005495 char *name;
5496 char *mode = "r";
5497 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005498 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005499 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005500 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005501 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005502 /* Strip mode of binary or text modifiers */
5503 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5504 mode = "r";
5505 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5506 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005507 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005508 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005509 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005510 if (fp == NULL)
5511 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005512 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005513 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005514 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005515 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005516}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005517
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005518#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005519#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005520
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005521
Guido van Rossumb6775db1994-08-01 11:34:53 +00005522#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005523PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005524"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005525Set the current process's user id.");
5526
Barry Warsaw53699e91996-12-10 23:23:01 +00005527static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005528posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005529{
Gregory P. Smithdd7b6302009-04-06 06:47:37 +00005530 long uid_arg;
5531 uid_t uid;
5532 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005533 return NULL;
Gregory P. Smithdd7b6302009-04-06 06:47:37 +00005534 uid = uid_arg;
5535 if (uid != uid_arg) {
5536 PyErr_SetString(PyExc_OverflowError, "user id too big");
5537 return NULL;
5538 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005539 if (setuid(uid) < 0)
5540 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005541 Py_INCREF(Py_None);
5542 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005543}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005544#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005545
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005546
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005547#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005548PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005549"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005550Set the current process's effective user id.");
5551
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005552static PyObject *
5553posix_seteuid (PyObject *self, PyObject *args)
5554{
Gregory P. Smithdd7b6302009-04-06 06:47:37 +00005555 long euid_arg;
5556 uid_t euid;
5557 if (!PyArg_ParseTuple(args, "l", &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005558 return NULL;
Gregory P. Smithdd7b6302009-04-06 06:47:37 +00005559 euid = euid_arg;
5560 if (euid != euid_arg) {
5561 PyErr_SetString(PyExc_OverflowError, "user id too big");
5562 return NULL;
5563 }
5564 if (seteuid(euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005565 return posix_error();
5566 } else {
5567 Py_INCREF(Py_None);
5568 return Py_None;
5569 }
5570}
5571#endif /* HAVE_SETEUID */
5572
5573#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005574PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005575"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005576Set the current process's effective group id.");
5577
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005578static PyObject *
5579posix_setegid (PyObject *self, PyObject *args)
5580{
Gregory P. Smithdd7b6302009-04-06 06:47:37 +00005581 long egid_arg;
5582 gid_t egid;
5583 if (!PyArg_ParseTuple(args, "l", &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005584 return NULL;
Gregory P. Smithdd7b6302009-04-06 06:47:37 +00005585 egid = egid_arg;
5586 if (egid != egid_arg) {
5587 PyErr_SetString(PyExc_OverflowError, "group id too big");
5588 return NULL;
5589 }
5590 if (setegid(egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005591 return posix_error();
5592 } else {
5593 Py_INCREF(Py_None);
5594 return Py_None;
5595 }
5596}
5597#endif /* HAVE_SETEGID */
5598
5599#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005600PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005601"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005602Set the current process's real and effective user ids.");
5603
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005604static PyObject *
5605posix_setreuid (PyObject *self, PyObject *args)
5606{
Gregory P. Smithdd7b6302009-04-06 06:47:37 +00005607 long ruid_arg, euid_arg;
5608 uid_t ruid, euid;
5609 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005610 return NULL;
Gregory P. Smithdd7b6302009-04-06 06:47:37 +00005611 ruid = ruid_arg;
5612 euid = euid_arg;
5613 if (euid != euid_arg || ruid != ruid_arg) {
5614 PyErr_SetString(PyExc_OverflowError, "user id too big");
5615 return NULL;
5616 }
5617 if (setreuid(ruid, euid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005618 return posix_error();
5619 } else {
5620 Py_INCREF(Py_None);
5621 return Py_None;
5622 }
5623}
5624#endif /* HAVE_SETREUID */
5625
5626#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005627PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005628"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005629Set the current process's real and effective group ids.");
5630
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005631static PyObject *
5632posix_setregid (PyObject *self, PyObject *args)
5633{
Gregory P. Smithdd7b6302009-04-06 06:47:37 +00005634 long rgid_arg, egid_arg;
5635 gid_t rgid, egid;
5636 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005637 return NULL;
Gregory P. Smithdd7b6302009-04-06 06:47:37 +00005638 rgid = rgid_arg;
5639 egid = egid_arg;
5640 if (egid != egid_arg || rgid != rgid_arg) {
5641 PyErr_SetString(PyExc_OverflowError, "group id too big");
5642 return NULL;
5643 }
5644 if (setregid(rgid, egid) < 0) {
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005645 return posix_error();
5646 } else {
5647 Py_INCREF(Py_None);
5648 return Py_None;
5649 }
5650}
5651#endif /* HAVE_SETREGID */
5652
Guido van Rossumb6775db1994-08-01 11:34:53 +00005653#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005654PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005655"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005656Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005657
Barry Warsaw53699e91996-12-10 23:23:01 +00005658static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005659posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005660{
Gregory P. Smithdd7b6302009-04-06 06:47:37 +00005661 long gid_arg;
5662 gid_t gid;
5663 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005664 return NULL;
Gregory P. Smithdd7b6302009-04-06 06:47:37 +00005665 gid = gid_arg;
5666 if (gid != gid_arg) {
5667 PyErr_SetString(PyExc_OverflowError, "group id too big");
5668 return NULL;
5669 }
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005670 if (setgid(gid) < 0)
5671 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005672 Py_INCREF(Py_None);
5673 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005674}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005675#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005676
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005677#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005678PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005679"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005680Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005681
5682static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005683posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005684{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005685 int i, len;
5686 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005687
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005688 if (!PySequence_Check(groups)) {
5689 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5690 return NULL;
5691 }
5692 len = PySequence_Size(groups);
5693 if (len > MAX_GROUPS) {
5694 PyErr_SetString(PyExc_ValueError, "too many groups");
5695 return NULL;
5696 }
5697 for(i = 0; i < len; i++) {
5698 PyObject *elem;
5699 elem = PySequence_GetItem(groups, i);
5700 if (!elem)
5701 return NULL;
5702 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005703 if (!PyLong_Check(elem)) {
5704 PyErr_SetString(PyExc_TypeError,
5705 "groups must be integers");
5706 Py_DECREF(elem);
5707 return NULL;
5708 } else {
5709 unsigned long x = PyLong_AsUnsignedLong(elem);
5710 if (PyErr_Occurred()) {
5711 PyErr_SetString(PyExc_TypeError,
5712 "group id too big");
5713 Py_DECREF(elem);
5714 return NULL;
5715 }
5716 grouplist[i] = x;
Gregory P. Smithdd7b6302009-04-06 06:47:37 +00005717 /* read back to see if it fits in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00005718 if (grouplist[i] != x) {
5719 PyErr_SetString(PyExc_TypeError,
5720 "group id too big");
5721 Py_DECREF(elem);
5722 return NULL;
5723 }
5724 }
5725 } else {
5726 long x = PyInt_AsLong(elem);
5727 grouplist[i] = x;
5728 if (grouplist[i] != x) {
5729 PyErr_SetString(PyExc_TypeError,
5730 "group id too big");
5731 Py_DECREF(elem);
5732 return NULL;
5733 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005734 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005735 Py_DECREF(elem);
5736 }
5737
5738 if (setgroups(len, grouplist) < 0)
5739 return posix_error();
5740 Py_INCREF(Py_None);
5741 return Py_None;
5742}
5743#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005744
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005745#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005746static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005747wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005748{
5749 PyObject *result;
5750 static PyObject *struct_rusage;
5751
5752 if (pid == -1)
5753 return posix_error();
5754
5755 if (struct_rusage == NULL) {
Christian Heimes000a0742008-01-03 22:16:32 +00005756 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Neal Norwitz05a45592006-03-20 06:30:08 +00005757 if (m == NULL)
5758 return NULL;
5759 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5760 Py_DECREF(m);
5761 if (struct_rusage == NULL)
5762 return NULL;
5763 }
5764
5765 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5766 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5767 if (!result)
5768 return NULL;
5769
5770#ifndef doubletime
5771#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5772#endif
5773
5774 PyStructSequence_SET_ITEM(result, 0,
5775 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5776 PyStructSequence_SET_ITEM(result, 1,
5777 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5778#define SET_INT(result, index, value)\
5779 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5780 SET_INT(result, 2, ru->ru_maxrss);
5781 SET_INT(result, 3, ru->ru_ixrss);
5782 SET_INT(result, 4, ru->ru_idrss);
5783 SET_INT(result, 5, ru->ru_isrss);
5784 SET_INT(result, 6, ru->ru_minflt);
5785 SET_INT(result, 7, ru->ru_majflt);
5786 SET_INT(result, 8, ru->ru_nswap);
5787 SET_INT(result, 9, ru->ru_inblock);
5788 SET_INT(result, 10, ru->ru_oublock);
5789 SET_INT(result, 11, ru->ru_msgsnd);
5790 SET_INT(result, 12, ru->ru_msgrcv);
5791 SET_INT(result, 13, ru->ru_nsignals);
5792 SET_INT(result, 14, ru->ru_nvcsw);
5793 SET_INT(result, 15, ru->ru_nivcsw);
5794#undef SET_INT
5795
5796 if (PyErr_Occurred()) {
5797 Py_DECREF(result);
5798 return NULL;
5799 }
5800
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00005801 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005802}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005803#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005804
5805#ifdef HAVE_WAIT3
5806PyDoc_STRVAR(posix_wait3__doc__,
5807"wait3(options) -> (pid, status, rusage)\n\n\
5808Wait for completion of a child process.");
5809
5810static PyObject *
5811posix_wait3(PyObject *self, PyObject *args)
5812{
Christian Heimesd491d712008-02-01 18:49:26 +00005813 pid_t pid;
5814 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005815 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005816 WAIT_TYPE status;
5817 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005818
5819 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5820 return NULL;
5821
5822 Py_BEGIN_ALLOW_THREADS
5823 pid = wait3(&status, options, &ru);
5824 Py_END_ALLOW_THREADS
5825
Neal Norwitzd5a37542006-03-20 06:48:34 +00005826 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005827}
5828#endif /* HAVE_WAIT3 */
5829
5830#ifdef HAVE_WAIT4
5831PyDoc_STRVAR(posix_wait4__doc__,
5832"wait4(pid, options) -> (pid, status, rusage)\n\n\
5833Wait for completion of a given child process.");
5834
5835static PyObject *
5836posix_wait4(PyObject *self, PyObject *args)
5837{
Christian Heimesd491d712008-02-01 18:49:26 +00005838 pid_t pid;
5839 int options;
Neal Norwitz05a45592006-03-20 06:30:08 +00005840 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005841 WAIT_TYPE status;
5842 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005843
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00005844 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
Neal Norwitz05a45592006-03-20 06:30:08 +00005845 return NULL;
5846
5847 Py_BEGIN_ALLOW_THREADS
5848 pid = wait4(pid, &status, options, &ru);
5849 Py_END_ALLOW_THREADS
5850
Neal Norwitzd5a37542006-03-20 06:48:34 +00005851 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005852}
5853#endif /* HAVE_WAIT4 */
5854
Guido van Rossumb6775db1994-08-01 11:34:53 +00005855#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005856PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005857"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005858Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005859
Barry Warsaw53699e91996-12-10 23:23:01 +00005860static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005861posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005862{
Christian Heimesd491d712008-02-01 18:49:26 +00005863 pid_t pid;
5864 int options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005865 WAIT_TYPE status;
5866 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005867
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00005868 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005869 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005870 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005871 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005872 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005873 if (pid == -1)
5874 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005875
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00005876 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005877}
5878
Tim Petersab034fa2002-02-01 11:27:43 +00005879#elif defined(HAVE_CWAIT)
5880
5881/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005882PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005883"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005884"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005885
5886static PyObject *
5887posix_waitpid(PyObject *self, PyObject *args)
5888{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005889 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005890 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005891
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00005892 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
Tim Petersab034fa2002-02-01 11:27:43 +00005893 return NULL;
5894 Py_BEGIN_ALLOW_THREADS
5895 pid = _cwait(&status, pid, options);
5896 Py_END_ALLOW_THREADS
5897 if (pid == -1)
5898 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005899
5900 /* shift the status left a byte so this is more like the POSIX waitpid */
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00005901 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005902}
5903#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005904
Guido van Rossumad0ee831995-03-01 10:34:45 +00005905#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005906PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005907"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005908Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005909
Barry Warsaw53699e91996-12-10 23:23:01 +00005910static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005911posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005912{
Christian Heimesd491d712008-02-01 18:49:26 +00005913 pid_t pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005914 WAIT_TYPE status;
5915 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005916
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005917 Py_BEGIN_ALLOW_THREADS
5918 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005919 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005920 if (pid == -1)
5921 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005922
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00005923 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005924}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005925#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005926
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005927
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005928PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005929"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005930Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005931
Barry Warsaw53699e91996-12-10 23:23:01 +00005932static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005933posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005934{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005935#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005936 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005937#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005938#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005939 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005940#else
5941 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5942#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005943#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005944}
5945
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005946
Guido van Rossumb6775db1994-08-01 11:34:53 +00005947#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005948PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005949"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005950Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005951
Barry Warsaw53699e91996-12-10 23:23:01 +00005952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005953posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005954{
Ronald Oussoren10168f22006-10-22 10:45:18 +00005955 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005956 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005957 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005958 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005959#ifdef Py_USING_UNICODE
5960 int arg_is_unicode = 0;
5961#endif
5962
5963 if (!PyArg_ParseTuple(args, "et:readlink",
5964 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005965 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005966#ifdef Py_USING_UNICODE
5967 v = PySequence_GetItem(args, 0);
Neal Norwitz91a57212007-08-12 17:11:13 +00005968 if (v == NULL) {
5969 PyMem_Free(path);
5970 return NULL;
5971 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00005972
5973 if (PyUnicode_Check(v)) {
5974 arg_is_unicode = 1;
5975 }
5976 Py_DECREF(v);
5977#endif
5978
Barry Warsaw53699e91996-12-10 23:23:01 +00005979 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005980 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005981 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005982 if (n < 0)
Neal Norwitz91a57212007-08-12 17:11:13 +00005983 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00005984
Neal Norwitz91a57212007-08-12 17:11:13 +00005985 PyMem_Free(path);
Gregory P. Smithdd96db62008-06-09 04:58:54 +00005986 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00005987#ifdef Py_USING_UNICODE
5988 if (arg_is_unicode) {
5989 PyObject *w;
5990
5991 w = PyUnicode_FromEncodedObject(v,
5992 Py_FileSystemDefaultEncoding,
5993 "strict");
5994 if (w != NULL) {
5995 Py_DECREF(v);
5996 v = w;
5997 }
5998 else {
5999 /* fall back to the original byte string, as
6000 discussed in patch #683592 */
6001 PyErr_Clear();
6002 }
6003 }
6004#endif
6005 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006006}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006007#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006008
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006009
Guido van Rossumb6775db1994-08-01 11:34:53 +00006010#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006011PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006012"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006013Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006014
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006016posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006017{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00006018 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006019}
6020#endif /* HAVE_SYMLINK */
6021
6022
6023#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006024#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6025static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006026system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006027{
6028 ULONG value = 0;
6029
6030 Py_BEGIN_ALLOW_THREADS
6031 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6032 Py_END_ALLOW_THREADS
6033
6034 return value;
6035}
6036
6037static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006038posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006039{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006040 /* Currently Only Uptime is Provided -- Others Later */
6041 return Py_BuildValue("ddddd",
6042 (double)0 /* t.tms_utime / HZ */,
6043 (double)0 /* t.tms_stime / HZ */,
6044 (double)0 /* t.tms_cutime / HZ */,
6045 (double)0 /* t.tms_cstime / HZ */,
6046 (double)system_uptime() / 1000);
6047}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006048#else /* not OS2 */
Martin v. Löwis3f15ae32008-12-29 18:20:48 +00006049#define NEED_TICKS_PER_SECOND
6050static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006051static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006052posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006053{
6054 struct tms t;
6055 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00006056 errno = 0;
6057 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00006058 if (c == (clock_t) -1)
6059 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006060 return Py_BuildValue("ddddd",
Martin v. Löwis3f15ae32008-12-29 18:20:48 +00006061 (double)t.tms_utime / ticks_per_second,
6062 (double)t.tms_stime / ticks_per_second,
6063 (double)t.tms_cutime / ticks_per_second,
6064 (double)t.tms_cstime / ticks_per_second,
6065 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006066}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006067#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006068#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006069
6070
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006071#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006072#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006073static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006074posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006075{
6076 FILETIME create, exit, kernel, user;
6077 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006078 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006079 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6080 /* The fields of a FILETIME structure are the hi and lo part
6081 of a 64-bit value expressed in 100 nanosecond units.
6082 1e7 is one second in such units; 1e-7 the inverse.
6083 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6084 */
Barry Warsaw53699e91996-12-10 23:23:01 +00006085 return Py_BuildValue(
6086 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00006087 (double)(user.dwHighDateTime*429.4967296 +
6088 user.dwLowDateTime*1e-7),
Georg Brandl0a40ffb2008-02-13 07:20:22 +00006089 (double)(kernel.dwHighDateTime*429.4967296 +
6090 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00006091 (double)0,
6092 (double)0,
6093 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006094}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006095#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006096
6097#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006098PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006099"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006100Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006101#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006102
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006103
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006104#ifdef HAVE_GETSID
6105PyDoc_STRVAR(posix_getsid__doc__,
6106"getsid(pid) -> sid\n\n\
6107Call the system call getsid().");
6108
6109static PyObject *
6110posix_getsid(PyObject *self, PyObject *args)
6111{
Christian Heimesd491d712008-02-01 18:49:26 +00006112 pid_t pid;
6113 int sid;
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00006114 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006115 return NULL;
6116 sid = getsid(pid);
6117 if (sid < 0)
6118 return posix_error();
6119 return PyInt_FromLong((long)sid);
6120}
6121#endif /* HAVE_GETSID */
6122
6123
Guido van Rossumb6775db1994-08-01 11:34:53 +00006124#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006125PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006126"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006127Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006128
Barry Warsaw53699e91996-12-10 23:23:01 +00006129static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006130posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006131{
Guido van Rossum687dd131993-05-17 08:34:16 +00006132 if (setsid() < 0)
6133 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006134 Py_INCREF(Py_None);
6135 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006136}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006137#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006138
Guido van Rossumb6775db1994-08-01 11:34:53 +00006139#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006140PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006141"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006142Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006143
Barry Warsaw53699e91996-12-10 23:23:01 +00006144static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006145posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006146{
Christian Heimesd491d712008-02-01 18:49:26 +00006147 pid_t pid;
6148 int pgrp;
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00006149 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00006150 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006151 if (setpgid(pid, pgrp) < 0)
6152 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006153 Py_INCREF(Py_None);
6154 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006155}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006156#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006157
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006158
Guido van Rossumb6775db1994-08-01 11:34:53 +00006159#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006160PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006161"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006162Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006163
Barry Warsaw53699e91996-12-10 23:23:01 +00006164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006165posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006166{
Christian Heimese6a80742008-02-03 19:51:13 +00006167 int fd;
6168 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006169 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006170 return NULL;
6171 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006172 if (pgid < 0)
6173 return posix_error();
Antoine Pitrou794b3fc2009-05-23 15:47:13 +00006174 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006175}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006176#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006177
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006178
Guido van Rossumb6775db1994-08-01 11:34:53 +00006179#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006180PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006181"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006182Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006183
Barry Warsaw53699e91996-12-10 23:23:01 +00006184static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006185posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006186{
Antoine Pitroucd1376d2009-05-23 16:19:24 +00006187 int fd;
6188 pid_t pgid;
6189 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006190 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006191 if (tcsetpgrp(fd, pgid) < 0)
6192 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00006193 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00006194 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006195}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006196#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006197
Guido van Rossum687dd131993-05-17 08:34:16 +00006198/* Functions acting on file descriptors */
6199
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006200PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006201"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006202Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006203
Barry Warsaw53699e91996-12-10 23:23:01 +00006204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006205posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006206{
Mark Hammondef8b6542001-05-13 08:04:26 +00006207 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006208 int flag;
6209 int mode = 0777;
6210 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006211
6212#ifdef MS_WINDOWS
6213 if (unicode_file_names()) {
6214 PyUnicodeObject *po;
6215 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6216 Py_BEGIN_ALLOW_THREADS
6217 /* PyUnicode_AS_UNICODE OK without thread
6218 lock as it is a simple dereference. */
6219 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6220 Py_END_ALLOW_THREADS
6221 if (fd < 0)
6222 return posix_error();
6223 return PyInt_FromLong((long)fd);
6224 }
6225 /* Drop the argument parsing error as narrow strings
6226 are also valid. */
6227 PyErr_Clear();
6228 }
6229#endif
6230
Tim Peters5aa91602002-01-30 05:46:57 +00006231 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006232 Py_FileSystemDefaultEncoding, &file,
6233 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006234 return NULL;
6235
Barry Warsaw53699e91996-12-10 23:23:01 +00006236 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006237 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006238 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006239 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006240 return posix_error_with_allocated_filename(file);
6241 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006242 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006243}
6244
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006245
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006246PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006247"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006248Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006249
Barry Warsaw53699e91996-12-10 23:23:01 +00006250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006251posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006252{
6253 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006254 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006255 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006256 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006257 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006258 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006259 if (res < 0)
6260 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006261 Py_INCREF(Py_None);
6262 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006263}
6264
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006265
Georg Brandl309501a2008-01-19 20:22:13 +00006266PyDoc_STRVAR(posix_closerange__doc__,
6267"closerange(fd_low, fd_high)\n\n\
6268Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6269
6270static PyObject *
6271posix_closerange(PyObject *self, PyObject *args)
6272{
6273 int fd_from, fd_to, i;
6274 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6275 return NULL;
6276 Py_BEGIN_ALLOW_THREADS
6277 for (i = fd_from; i < fd_to; i++)
6278 close(i);
6279 Py_END_ALLOW_THREADS
6280 Py_RETURN_NONE;
6281}
6282
6283
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006284PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006285"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006286Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006287
Barry Warsaw53699e91996-12-10 23:23:01 +00006288static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006289posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006290{
6291 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006292 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006293 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006294 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006295 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006296 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006297 if (fd < 0)
6298 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006299 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006300}
6301
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006302
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006303PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006304"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006305Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006306
Barry Warsaw53699e91996-12-10 23:23:01 +00006307static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006308posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006309{
6310 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006311 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006312 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006313 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006314 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006315 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006316 if (res < 0)
6317 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006318 Py_INCREF(Py_None);
6319 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006320}
6321
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006322
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006323PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006324"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006325Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006326
Barry Warsaw53699e91996-12-10 23:23:01 +00006327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006328posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006329{
6330 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006331#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006332 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006333#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006334 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006335#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006336 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006337 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006338 return NULL;
6339#ifdef SEEK_SET
6340 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6341 switch (how) {
6342 case 0: how = SEEK_SET; break;
6343 case 1: how = SEEK_CUR; break;
6344 case 2: how = SEEK_END; break;
6345 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006346#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006347
6348#if !defined(HAVE_LARGEFILE_SUPPORT)
6349 pos = PyInt_AsLong(posobj);
6350#else
6351 pos = PyLong_Check(posobj) ?
6352 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6353#endif
6354 if (PyErr_Occurred())
6355 return NULL;
6356
Barry Warsaw53699e91996-12-10 23:23:01 +00006357 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006358#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006359 res = _lseeki64(fd, pos, how);
6360#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006361 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006362#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006363 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006364 if (res < 0)
6365 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006366
6367#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006368 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006369#else
6370 return PyLong_FromLongLong(res);
6371#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006372}
6373
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006374
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006375PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006376"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006377Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006378
Barry Warsaw53699e91996-12-10 23:23:01 +00006379static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006380posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006381{
Guido van Rossum8bac5461996-06-11 18:38:48 +00006382 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006383 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006384 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006385 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006386 if (size < 0) {
6387 errno = EINVAL;
6388 return posix_error();
6389 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006390 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006391 if (buffer == NULL)
6392 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006393 Py_BEGIN_ALLOW_THREADS
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006394 n = read(fd, PyString_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006395 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006396 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006397 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006398 return posix_error();
6399 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006400 if (n != size)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006401 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006402 return buffer;
6403}
6404
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006405
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006406PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006407"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006408Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006409
Barry Warsaw53699e91996-12-10 23:23:01 +00006410static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006411posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006412{
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006413 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006414 int fd;
6415 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006416
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006417 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00006418 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006419 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006420 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00006421 Py_END_ALLOW_THREADS
Martin v. Löwisf91d46a2008-08-12 14:49:50 +00006422 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00006423 if (size < 0)
6424 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006425 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006426}
6427
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006428
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006429PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006430"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006431Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006432
Barry Warsaw53699e91996-12-10 23:23:01 +00006433static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006434posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006435{
6436 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006437 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006438 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006439 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006440 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006441#ifdef __VMS
6442 /* on OpenVMS we must ensure that all bytes are written to the file */
6443 fsync(fd);
6444#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006445 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006446 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006447 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006448 if (res != 0) {
6449#ifdef MS_WINDOWS
6450 return win32_error("fstat", NULL);
6451#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006452 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006453#endif
6454 }
Tim Peters5aa91602002-01-30 05:46:57 +00006455
Martin v. Löwis14694662006-02-03 12:54:16 +00006456 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006457}
6458
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006459
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006460PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006461"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006462Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006463
Barry Warsaw53699e91996-12-10 23:23:01 +00006464static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006465posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006466{
Guido van Rossum687dd131993-05-17 08:34:16 +00006467 int fd;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006468 char *orgmode = "r";
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006469 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006470 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006471 PyObject *f;
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006472 char *mode;
6473 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006474 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006475
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006476 /* Sanitize mode. See fileobject.c */
6477 mode = PyMem_MALLOC(strlen(orgmode)+3);
6478 if (!mode) {
6479 PyErr_NoMemory();
6480 return NULL;
6481 }
6482 strcpy(mode, orgmode);
6483 if (_PyFile_SanitizeMode(mode)) {
6484 PyMem_FREE(mode);
Thomas Heller1f043e22002-11-07 16:00:59 +00006485 return NULL;
6486 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006487 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006488#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006489 if (mode[0] == 'a') {
6490 /* try to make sure the O_APPEND flag is set */
6491 int flags;
6492 flags = fcntl(fd, F_GETFL);
6493 if (flags != -1)
6494 fcntl(fd, F_SETFL, flags | O_APPEND);
6495 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006496 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006497 /* restore old mode if fdopen failed */
6498 fcntl(fd, F_SETFL, flags);
6499 } else {
6500 fp = fdopen(fd, mode);
6501 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006502#else
6503 fp = fdopen(fd, mode);
6504#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006505 Py_END_ALLOW_THREADS
Neal Norwitzd83eb312007-05-02 04:47:55 +00006506 PyMem_FREE(mode);
Guido van Rossum687dd131993-05-17 08:34:16 +00006507 if (fp == NULL)
6508 return posix_error();
Kristján Valur Jónsson0a440d42007-04-26 09:15:08 +00006509 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006510 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006511 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006512 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006513}
6514
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006515PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006516"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006517Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006518connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006519
6520static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006521posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006522{
6523 int fd;
6524 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6525 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006526 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006527}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006528
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006529#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006530PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006531"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006532Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006533
Barry Warsaw53699e91996-12-10 23:23:01 +00006534static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006535posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006536{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006537#if defined(PYOS_OS2)
6538 HFILE read, write;
6539 APIRET rc;
6540
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006541 Py_BEGIN_ALLOW_THREADS
6542 rc = DosCreatePipe( &read, &write, 4096);
6543 Py_END_ALLOW_THREADS
6544 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006545 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006546
6547 return Py_BuildValue("(ii)", read, write);
6548#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006549#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006550 int fds[2];
6551 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006552 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006553 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006554 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006555 if (res != 0)
6556 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006557 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006558#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006559 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006560 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006561 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006562 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006563 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006564 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006565 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006566 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006567 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6568 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006569 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006570#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006571#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006572}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006573#endif /* HAVE_PIPE */
6574
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006575
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006576#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006577PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006578"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006579Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006580
Barry Warsaw53699e91996-12-10 23:23:01 +00006581static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006582posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006583{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006584 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006585 int mode = 0666;
6586 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006587 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006588 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006589 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006590 res = mkfifo(filename, mode);
6591 Py_END_ALLOW_THREADS
6592 if (res < 0)
6593 return posix_error();
6594 Py_INCREF(Py_None);
6595 return Py_None;
6596}
6597#endif
6598
6599
Neal Norwitz11690112002-07-30 01:08:28 +00006600#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006601PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006602"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006603Create a filesystem node (file, device special file or named pipe)\n\
6604named filename. mode specifies both the permissions to use and the\n\
6605type of node to be created, being combined (bitwise OR) with one of\n\
6606S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006607device defines the newly created device special file (probably using\n\
6608os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006609
6610
6611static PyObject *
6612posix_mknod(PyObject *self, PyObject *args)
6613{
6614 char *filename;
6615 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006616 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006617 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006618 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006619 return NULL;
6620 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006621 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006622 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006623 if (res < 0)
6624 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006625 Py_INCREF(Py_None);
6626 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006627}
6628#endif
6629
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006630#ifdef HAVE_DEVICE_MACROS
6631PyDoc_STRVAR(posix_major__doc__,
6632"major(device) -> major number\n\
6633Extracts a device major number from a raw device number.");
6634
6635static PyObject *
6636posix_major(PyObject *self, PyObject *args)
6637{
6638 int device;
6639 if (!PyArg_ParseTuple(args, "i:major", &device))
6640 return NULL;
6641 return PyInt_FromLong((long)major(device));
6642}
6643
6644PyDoc_STRVAR(posix_minor__doc__,
6645"minor(device) -> minor number\n\
6646Extracts a device minor number from a raw device number.");
6647
6648static PyObject *
6649posix_minor(PyObject *self, PyObject *args)
6650{
6651 int device;
6652 if (!PyArg_ParseTuple(args, "i:minor", &device))
6653 return NULL;
6654 return PyInt_FromLong((long)minor(device));
6655}
6656
6657PyDoc_STRVAR(posix_makedev__doc__,
6658"makedev(major, minor) -> device number\n\
6659Composes a raw device number from the major and minor device numbers.");
6660
6661static PyObject *
6662posix_makedev(PyObject *self, PyObject *args)
6663{
6664 int major, minor;
6665 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6666 return NULL;
6667 return PyInt_FromLong((long)makedev(major, minor));
6668}
6669#endif /* device macros */
6670
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006671
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006672#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006673PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006674"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006675Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006676
Barry Warsaw53699e91996-12-10 23:23:01 +00006677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006678posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006679{
6680 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006681 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006682 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006683 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006684
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006685 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006686 return NULL;
6687
6688#if !defined(HAVE_LARGEFILE_SUPPORT)
6689 length = PyInt_AsLong(lenobj);
6690#else
6691 length = PyLong_Check(lenobj) ?
6692 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6693#endif
6694 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006695 return NULL;
6696
Barry Warsaw53699e91996-12-10 23:23:01 +00006697 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006698 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006699 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006700 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006701 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006702 return NULL;
6703 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006704 Py_INCREF(Py_None);
6705 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006706}
6707#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006708
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006709#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006710PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006711"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006712Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006713
Fred Drake762e2061999-08-26 17:23:54 +00006714/* Save putenv() parameters as values here, so we can collect them when they
6715 * get re-set with another call for the same key. */
6716static PyObject *posix_putenv_garbage;
6717
Tim Peters5aa91602002-01-30 05:46:57 +00006718static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006719posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006720{
6721 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006722 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006723 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006724 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006725
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006726 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006727 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006728
6729#if defined(PYOS_OS2)
6730 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6731 APIRET rc;
6732
Guido van Rossumd48f2521997-12-05 22:19:34 +00006733 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6734 if (rc != NO_ERROR)
6735 return os2_error(rc);
6736
6737 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6738 APIRET rc;
6739
Guido van Rossumd48f2521997-12-05 22:19:34 +00006740 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6741 if (rc != NO_ERROR)
6742 return os2_error(rc);
6743 } else {
6744#endif
6745
Fred Drake762e2061999-08-26 17:23:54 +00006746 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006747 len = strlen(s1) + strlen(s2) + 2;
6748 /* len includes space for a trailing \0; the size arg to
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006749 PyString_FromStringAndSize does not count that */
6750 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006751 if (newstr == NULL)
6752 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006753 newenv = PyString_AS_STRING(newstr);
Anthony Baxter64182fe2006-04-11 12:14:09 +00006754 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6755 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006756 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006757 posix_error();
6758 return NULL;
6759 }
Fred Drake762e2061999-08-26 17:23:54 +00006760 /* Install the first arg and newstr in posix_putenv_garbage;
6761 * this will cause previous value to be collected. This has to
6762 * happen after the real putenv() call because the old value
6763 * was still accessible until then. */
6764 if (PyDict_SetItem(posix_putenv_garbage,
6765 PyTuple_GET_ITEM(args, 0), newstr)) {
6766 /* really not much we can do; just leak */
6767 PyErr_Clear();
6768 }
6769 else {
6770 Py_DECREF(newstr);
6771 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006772
6773#if defined(PYOS_OS2)
6774 }
6775#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006776 Py_INCREF(Py_None);
6777 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006778}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006779#endif /* putenv */
6780
Guido van Rossumc524d952001-10-19 01:31:59 +00006781#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006782PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006783"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006784Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006785
6786static PyObject *
6787posix_unsetenv(PyObject *self, PyObject *args)
6788{
6789 char *s1;
6790
6791 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6792 return NULL;
6793
6794 unsetenv(s1);
6795
6796 /* Remove the key from posix_putenv_garbage;
6797 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006798 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006799 * old value was still accessible until then.
6800 */
6801 if (PyDict_DelItem(posix_putenv_garbage,
6802 PyTuple_GET_ITEM(args, 0))) {
6803 /* really not much we can do; just leak */
6804 PyErr_Clear();
6805 }
6806
6807 Py_INCREF(Py_None);
6808 return Py_None;
6809}
6810#endif /* unsetenv */
6811
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006812PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006813"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006814Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006815
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006817posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006818{
6819 int code;
6820 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006821 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006822 return NULL;
6823 message = strerror(code);
6824 if (message == NULL) {
6825 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006826 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006827 return NULL;
6828 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00006829 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006830}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006831
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006832
Guido van Rossumc9641791998-08-04 15:26:23 +00006833#ifdef HAVE_SYS_WAIT_H
6834
Fred Drake106c1a02002-04-23 15:58:02 +00006835#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006836PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006837"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006838Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006839
6840static PyObject *
6841posix_WCOREDUMP(PyObject *self, PyObject *args)
6842{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006843 WAIT_TYPE status;
6844 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006845
Neal Norwitzd5a37542006-03-20 06:48:34 +00006846 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006847 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006848
6849 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006850}
6851#endif /* WCOREDUMP */
6852
6853#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006854PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006855"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006856Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006857job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006858
6859static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006860posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006861{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006862 WAIT_TYPE status;
6863 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006864
Neal Norwitzd5a37542006-03-20 06:48:34 +00006865 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006866 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006867
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006868 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006869}
6870#endif /* WIFCONTINUED */
6871
Guido van Rossumc9641791998-08-04 15:26:23 +00006872#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006873PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006874"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006875Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006876
6877static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006878posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006879{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006880 WAIT_TYPE status;
6881 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006882
Neal Norwitzd5a37542006-03-20 06:48:34 +00006883 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006884 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006885
Fred Drake106c1a02002-04-23 15:58:02 +00006886 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006887}
6888#endif /* WIFSTOPPED */
6889
6890#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006891PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006892"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006893Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006894
6895static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006896posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006897{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006898 WAIT_TYPE status;
6899 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006900
Neal Norwitzd5a37542006-03-20 06:48:34 +00006901 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006902 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006903
Fred Drake106c1a02002-04-23 15:58:02 +00006904 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006905}
6906#endif /* WIFSIGNALED */
6907
6908#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006909PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006910"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006911Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006912system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006913
6914static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006915posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006916{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006917 WAIT_TYPE status;
6918 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006919
Neal Norwitzd5a37542006-03-20 06:48:34 +00006920 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006921 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006922
Fred Drake106c1a02002-04-23 15:58:02 +00006923 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006924}
6925#endif /* WIFEXITED */
6926
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006927#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006928PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006929"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006930Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006931
6932static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006933posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006934{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006935 WAIT_TYPE status;
6936 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006937
Neal Norwitzd5a37542006-03-20 06:48:34 +00006938 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006939 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006940
Guido van Rossumc9641791998-08-04 15:26:23 +00006941 return Py_BuildValue("i", WEXITSTATUS(status));
6942}
6943#endif /* WEXITSTATUS */
6944
6945#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006946PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006947"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006948Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006949value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006950
6951static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006952posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006953{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006954 WAIT_TYPE status;
6955 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006956
Neal Norwitzd5a37542006-03-20 06:48:34 +00006957 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006958 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006959
Guido van Rossumc9641791998-08-04 15:26:23 +00006960 return Py_BuildValue("i", WTERMSIG(status));
6961}
6962#endif /* WTERMSIG */
6963
6964#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006965PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006966"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006967Return the signal that stopped the process that provided\n\
6968the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006969
6970static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006971posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006972{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006973 WAIT_TYPE status;
6974 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006975
Neal Norwitzd5a37542006-03-20 06:48:34 +00006976 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006977 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006978
Guido van Rossumc9641791998-08-04 15:26:23 +00006979 return Py_BuildValue("i", WSTOPSIG(status));
6980}
6981#endif /* WSTOPSIG */
6982
6983#endif /* HAVE_SYS_WAIT_H */
6984
6985
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006986#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006987#ifdef _SCO_DS
6988/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6989 needed definitions in sys/statvfs.h */
6990#define _SVID3
6991#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006992#include <sys/statvfs.h>
6993
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006994static PyObject*
6995_pystatvfs_fromstructstatvfs(struct statvfs st) {
6996 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6997 if (v == NULL)
6998 return NULL;
6999
7000#if !defined(HAVE_LARGEFILE_SUPPORT)
7001 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7002 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7003 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7004 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7005 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7006 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7007 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7008 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7009 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7010 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7011#else
7012 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7013 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00007014 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007015 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00007016 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007017 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007018 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007019 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00007020 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007021 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00007022 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007023 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00007024 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00007025 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007026 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7027 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7028#endif
7029
7030 return v;
7031}
7032
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007033PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007034"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007035Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007036
7037static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007038posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007039{
7040 int fd, res;
7041 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007042
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007043 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007044 return NULL;
7045 Py_BEGIN_ALLOW_THREADS
7046 res = fstatvfs(fd, &st);
7047 Py_END_ALLOW_THREADS
7048 if (res != 0)
7049 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007050
7051 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007052}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007053#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007054
7055
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007056#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007057#include <sys/statvfs.h>
7058
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007059PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007060"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007061Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007062
7063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007064posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007065{
7066 char *path;
7067 int res;
7068 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007069 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00007070 return NULL;
7071 Py_BEGIN_ALLOW_THREADS
7072 res = statvfs(path, &st);
7073 Py_END_ALLOW_THREADS
7074 if (res != 0)
7075 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007076
7077 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007078}
7079#endif /* HAVE_STATVFS */
7080
7081
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007082#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007083PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007084"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007085Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007086The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007087or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007088
7089static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007090posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007091{
7092 PyObject *result = NULL;
7093 char *dir = NULL;
7094 char *pfx = NULL;
7095 char *name;
7096
7097 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7098 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007099
7100 if (PyErr_Warn(PyExc_RuntimeWarning,
7101 "tempnam is a potential security risk to your program") < 0)
7102 return NULL;
7103
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007104#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007105 name = _tempnam(dir, pfx);
7106#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007107 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007108#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007109 if (name == NULL)
7110 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007111 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007112 free(name);
7113 return result;
7114}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007115#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007116
7117
7118#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007119PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007120"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007121Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007122
7123static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007124posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007125{
7126 FILE *fp;
7127
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007128 fp = tmpfile();
7129 if (fp == NULL)
7130 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007131 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007132}
7133#endif
7134
7135
7136#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007137PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007138"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007139Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007140
7141static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007142posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007143{
7144 char buffer[L_tmpnam];
7145 char *name;
7146
Skip Montanaro95618b52001-08-18 18:52:10 +00007147 if (PyErr_Warn(PyExc_RuntimeWarning,
7148 "tmpnam is a potential security risk to your program") < 0)
7149 return NULL;
7150
Greg Wardb48bc172000-03-01 21:51:56 +00007151#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007152 name = tmpnam_r(buffer);
7153#else
7154 name = tmpnam(buffer);
7155#endif
7156 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007157 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007158#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007159 "unexpected NULL from tmpnam_r"
7160#else
7161 "unexpected NULL from tmpnam"
7162#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00007163 );
7164 PyErr_SetObject(PyExc_OSError, err);
7165 Py_XDECREF(err);
7166 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007167 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007168 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007169}
7170#endif
7171
7172
Fred Drakec9680921999-12-13 16:37:25 +00007173/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7174 * It maps strings representing configuration variable names to
7175 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007176 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007177 * rarely-used constants. There are three separate tables that use
7178 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007179 *
7180 * This code is always included, even if none of the interfaces that
7181 * need it are included. The #if hackery needed to avoid it would be
7182 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007183 */
7184struct constdef {
7185 char *name;
7186 long value;
7187};
7188
Fred Drake12c6e2d1999-12-14 21:25:03 +00007189static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007190conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7191 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007192{
7193 if (PyInt_Check(arg)) {
7194 *valuep = PyInt_AS_LONG(arg);
7195 return 1;
7196 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007197 if (PyString_Check(arg)) {
Fred Drake12c6e2d1999-12-14 21:25:03 +00007198 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00007199 size_t lo = 0;
7200 size_t mid;
7201 size_t hi = tablesize;
7202 int cmp;
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007203 char *confname = PyString_AS_STRING(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007204 while (lo < hi) {
7205 mid = (lo + hi) / 2;
7206 cmp = strcmp(confname, table[mid].name);
7207 if (cmp < 0)
7208 hi = mid;
7209 else if (cmp > 0)
7210 lo = mid + 1;
7211 else {
7212 *valuep = table[mid].value;
7213 return 1;
7214 }
7215 }
7216 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7217 }
7218 else
7219 PyErr_SetString(PyExc_TypeError,
7220 "configuration names must be strings or integers");
7221 return 0;
7222}
7223
7224
7225#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7226static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007227#ifdef _PC_ABI_AIO_XFER_MAX
7228 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7229#endif
7230#ifdef _PC_ABI_ASYNC_IO
7231 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7232#endif
Fred Drakec9680921999-12-13 16:37:25 +00007233#ifdef _PC_ASYNC_IO
7234 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7235#endif
7236#ifdef _PC_CHOWN_RESTRICTED
7237 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7238#endif
7239#ifdef _PC_FILESIZEBITS
7240 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7241#endif
7242#ifdef _PC_LAST
7243 {"PC_LAST", _PC_LAST},
7244#endif
7245#ifdef _PC_LINK_MAX
7246 {"PC_LINK_MAX", _PC_LINK_MAX},
7247#endif
7248#ifdef _PC_MAX_CANON
7249 {"PC_MAX_CANON", _PC_MAX_CANON},
7250#endif
7251#ifdef _PC_MAX_INPUT
7252 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7253#endif
7254#ifdef _PC_NAME_MAX
7255 {"PC_NAME_MAX", _PC_NAME_MAX},
7256#endif
7257#ifdef _PC_NO_TRUNC
7258 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7259#endif
7260#ifdef _PC_PATH_MAX
7261 {"PC_PATH_MAX", _PC_PATH_MAX},
7262#endif
7263#ifdef _PC_PIPE_BUF
7264 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7265#endif
7266#ifdef _PC_PRIO_IO
7267 {"PC_PRIO_IO", _PC_PRIO_IO},
7268#endif
7269#ifdef _PC_SOCK_MAXBUF
7270 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7271#endif
7272#ifdef _PC_SYNC_IO
7273 {"PC_SYNC_IO", _PC_SYNC_IO},
7274#endif
7275#ifdef _PC_VDISABLE
7276 {"PC_VDISABLE", _PC_VDISABLE},
7277#endif
7278};
7279
Fred Drakec9680921999-12-13 16:37:25 +00007280static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007281conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007282{
7283 return conv_confname(arg, valuep, posix_constants_pathconf,
7284 sizeof(posix_constants_pathconf)
7285 / sizeof(struct constdef));
7286}
7287#endif
7288
7289#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007290PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007291"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007292Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007293If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007294
7295static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007296posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007297{
7298 PyObject *result = NULL;
7299 int name, fd;
7300
Fred Drake12c6e2d1999-12-14 21:25:03 +00007301 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7302 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00007303 long limit;
7304
7305 errno = 0;
7306 limit = fpathconf(fd, name);
7307 if (limit == -1 && errno != 0)
7308 posix_error();
7309 else
7310 result = PyInt_FromLong(limit);
7311 }
7312 return result;
7313}
7314#endif
7315
7316
7317#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007318PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007319"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007320Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007321If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007322
7323static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007324posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007325{
7326 PyObject *result = NULL;
7327 int name;
7328 char *path;
7329
7330 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7331 conv_path_confname, &name)) {
7332 long limit;
7333
7334 errno = 0;
7335 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007336 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00007337 if (errno == EINVAL)
7338 /* could be a path or name problem */
7339 posix_error();
7340 else
7341 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007342 }
Fred Drakec9680921999-12-13 16:37:25 +00007343 else
7344 result = PyInt_FromLong(limit);
7345 }
7346 return result;
7347}
7348#endif
7349
7350#ifdef HAVE_CONFSTR
7351static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007352#ifdef _CS_ARCHITECTURE
7353 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7354#endif
7355#ifdef _CS_HOSTNAME
7356 {"CS_HOSTNAME", _CS_HOSTNAME},
7357#endif
7358#ifdef _CS_HW_PROVIDER
7359 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7360#endif
7361#ifdef _CS_HW_SERIAL
7362 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7363#endif
7364#ifdef _CS_INITTAB_NAME
7365 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7366#endif
Fred Drakec9680921999-12-13 16:37:25 +00007367#ifdef _CS_LFS64_CFLAGS
7368 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7369#endif
7370#ifdef _CS_LFS64_LDFLAGS
7371 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7372#endif
7373#ifdef _CS_LFS64_LIBS
7374 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7375#endif
7376#ifdef _CS_LFS64_LINTFLAGS
7377 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7378#endif
7379#ifdef _CS_LFS_CFLAGS
7380 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7381#endif
7382#ifdef _CS_LFS_LDFLAGS
7383 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7384#endif
7385#ifdef _CS_LFS_LIBS
7386 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7387#endif
7388#ifdef _CS_LFS_LINTFLAGS
7389 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7390#endif
Fred Draked86ed291999-12-15 15:34:33 +00007391#ifdef _CS_MACHINE
7392 {"CS_MACHINE", _CS_MACHINE},
7393#endif
Fred Drakec9680921999-12-13 16:37:25 +00007394#ifdef _CS_PATH
7395 {"CS_PATH", _CS_PATH},
7396#endif
Fred Draked86ed291999-12-15 15:34:33 +00007397#ifdef _CS_RELEASE
7398 {"CS_RELEASE", _CS_RELEASE},
7399#endif
7400#ifdef _CS_SRPC_DOMAIN
7401 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7402#endif
7403#ifdef _CS_SYSNAME
7404 {"CS_SYSNAME", _CS_SYSNAME},
7405#endif
7406#ifdef _CS_VERSION
7407 {"CS_VERSION", _CS_VERSION},
7408#endif
Fred Drakec9680921999-12-13 16:37:25 +00007409#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7410 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7411#endif
7412#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7413 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7414#endif
7415#ifdef _CS_XBS5_ILP32_OFF32_LIBS
7416 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7417#endif
7418#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7419 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7420#endif
7421#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7422 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7423#endif
7424#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7425 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7426#endif
7427#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7428 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7429#endif
7430#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7431 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7432#endif
7433#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7434 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7435#endif
7436#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7437 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7438#endif
7439#ifdef _CS_XBS5_LP64_OFF64_LIBS
7440 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7441#endif
7442#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7443 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7444#endif
7445#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7446 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7447#endif
7448#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7449 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7450#endif
7451#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7452 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7453#endif
7454#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7455 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7456#endif
Fred Draked86ed291999-12-15 15:34:33 +00007457#ifdef _MIPS_CS_AVAIL_PROCESSORS
7458 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7459#endif
7460#ifdef _MIPS_CS_BASE
7461 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7462#endif
7463#ifdef _MIPS_CS_HOSTID
7464 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7465#endif
7466#ifdef _MIPS_CS_HW_NAME
7467 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7468#endif
7469#ifdef _MIPS_CS_NUM_PROCESSORS
7470 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7471#endif
7472#ifdef _MIPS_CS_OSREL_MAJ
7473 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7474#endif
7475#ifdef _MIPS_CS_OSREL_MIN
7476 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7477#endif
7478#ifdef _MIPS_CS_OSREL_PATCH
7479 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7480#endif
7481#ifdef _MIPS_CS_OS_NAME
7482 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7483#endif
7484#ifdef _MIPS_CS_OS_PROVIDER
7485 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7486#endif
7487#ifdef _MIPS_CS_PROCESSORS
7488 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7489#endif
7490#ifdef _MIPS_CS_SERIAL
7491 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7492#endif
7493#ifdef _MIPS_CS_VENDOR
7494 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7495#endif
Fred Drakec9680921999-12-13 16:37:25 +00007496};
7497
7498static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007499conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007500{
7501 return conv_confname(arg, valuep, posix_constants_confstr,
7502 sizeof(posix_constants_confstr)
7503 / sizeof(struct constdef));
7504}
7505
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007506PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007507"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007508Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007509
7510static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007511posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007512{
7513 PyObject *result = NULL;
7514 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007515 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007516
7517 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007518 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007519
Fred Drakec9680921999-12-13 16:37:25 +00007520 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007521 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007522 if (len == 0) {
7523 if (errno) {
7524 posix_error();
7525 }
7526 else {
7527 result = Py_None;
7528 Py_INCREF(Py_None);
7529 }
Fred Drakec9680921999-12-13 16:37:25 +00007530 }
7531 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007532 if ((unsigned int)len >= sizeof(buffer)) {
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007533 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007534 if (result != NULL)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007535 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007536 }
7537 else
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007538 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007539 }
7540 }
7541 return result;
7542}
7543#endif
7544
7545
7546#ifdef HAVE_SYSCONF
7547static struct constdef posix_constants_sysconf[] = {
7548#ifdef _SC_2_CHAR_TERM
7549 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7550#endif
7551#ifdef _SC_2_C_BIND
7552 {"SC_2_C_BIND", _SC_2_C_BIND},
7553#endif
7554#ifdef _SC_2_C_DEV
7555 {"SC_2_C_DEV", _SC_2_C_DEV},
7556#endif
7557#ifdef _SC_2_C_VERSION
7558 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7559#endif
7560#ifdef _SC_2_FORT_DEV
7561 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7562#endif
7563#ifdef _SC_2_FORT_RUN
7564 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7565#endif
7566#ifdef _SC_2_LOCALEDEF
7567 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7568#endif
7569#ifdef _SC_2_SW_DEV
7570 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7571#endif
7572#ifdef _SC_2_UPE
7573 {"SC_2_UPE", _SC_2_UPE},
7574#endif
7575#ifdef _SC_2_VERSION
7576 {"SC_2_VERSION", _SC_2_VERSION},
7577#endif
Fred Draked86ed291999-12-15 15:34:33 +00007578#ifdef _SC_ABI_ASYNCHRONOUS_IO
7579 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7580#endif
7581#ifdef _SC_ACL
7582 {"SC_ACL", _SC_ACL},
7583#endif
Fred Drakec9680921999-12-13 16:37:25 +00007584#ifdef _SC_AIO_LISTIO_MAX
7585 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7586#endif
Fred Drakec9680921999-12-13 16:37:25 +00007587#ifdef _SC_AIO_MAX
7588 {"SC_AIO_MAX", _SC_AIO_MAX},
7589#endif
7590#ifdef _SC_AIO_PRIO_DELTA_MAX
7591 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7592#endif
7593#ifdef _SC_ARG_MAX
7594 {"SC_ARG_MAX", _SC_ARG_MAX},
7595#endif
7596#ifdef _SC_ASYNCHRONOUS_IO
7597 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7598#endif
7599#ifdef _SC_ATEXIT_MAX
7600 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7601#endif
Fred Draked86ed291999-12-15 15:34:33 +00007602#ifdef _SC_AUDIT
7603 {"SC_AUDIT", _SC_AUDIT},
7604#endif
Fred Drakec9680921999-12-13 16:37:25 +00007605#ifdef _SC_AVPHYS_PAGES
7606 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7607#endif
7608#ifdef _SC_BC_BASE_MAX
7609 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7610#endif
7611#ifdef _SC_BC_DIM_MAX
7612 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7613#endif
7614#ifdef _SC_BC_SCALE_MAX
7615 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7616#endif
7617#ifdef _SC_BC_STRING_MAX
7618 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7619#endif
Fred Draked86ed291999-12-15 15:34:33 +00007620#ifdef _SC_CAP
7621 {"SC_CAP", _SC_CAP},
7622#endif
Fred Drakec9680921999-12-13 16:37:25 +00007623#ifdef _SC_CHARCLASS_NAME_MAX
7624 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7625#endif
7626#ifdef _SC_CHAR_BIT
7627 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7628#endif
7629#ifdef _SC_CHAR_MAX
7630 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7631#endif
7632#ifdef _SC_CHAR_MIN
7633 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7634#endif
7635#ifdef _SC_CHILD_MAX
7636 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7637#endif
7638#ifdef _SC_CLK_TCK
7639 {"SC_CLK_TCK", _SC_CLK_TCK},
7640#endif
7641#ifdef _SC_COHER_BLKSZ
7642 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7643#endif
7644#ifdef _SC_COLL_WEIGHTS_MAX
7645 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7646#endif
7647#ifdef _SC_DCACHE_ASSOC
7648 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7649#endif
7650#ifdef _SC_DCACHE_BLKSZ
7651 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7652#endif
7653#ifdef _SC_DCACHE_LINESZ
7654 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7655#endif
7656#ifdef _SC_DCACHE_SZ
7657 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7658#endif
7659#ifdef _SC_DCACHE_TBLKSZ
7660 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7661#endif
7662#ifdef _SC_DELAYTIMER_MAX
7663 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7664#endif
7665#ifdef _SC_EQUIV_CLASS_MAX
7666 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7667#endif
7668#ifdef _SC_EXPR_NEST_MAX
7669 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7670#endif
7671#ifdef _SC_FSYNC
7672 {"SC_FSYNC", _SC_FSYNC},
7673#endif
7674#ifdef _SC_GETGR_R_SIZE_MAX
7675 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7676#endif
7677#ifdef _SC_GETPW_R_SIZE_MAX
7678 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7679#endif
7680#ifdef _SC_ICACHE_ASSOC
7681 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7682#endif
7683#ifdef _SC_ICACHE_BLKSZ
7684 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7685#endif
7686#ifdef _SC_ICACHE_LINESZ
7687 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7688#endif
7689#ifdef _SC_ICACHE_SZ
7690 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7691#endif
Fred Draked86ed291999-12-15 15:34:33 +00007692#ifdef _SC_INF
7693 {"SC_INF", _SC_INF},
7694#endif
Fred Drakec9680921999-12-13 16:37:25 +00007695#ifdef _SC_INT_MAX
7696 {"SC_INT_MAX", _SC_INT_MAX},
7697#endif
7698#ifdef _SC_INT_MIN
7699 {"SC_INT_MIN", _SC_INT_MIN},
7700#endif
7701#ifdef _SC_IOV_MAX
7702 {"SC_IOV_MAX", _SC_IOV_MAX},
7703#endif
Fred Draked86ed291999-12-15 15:34:33 +00007704#ifdef _SC_IP_SECOPTS
7705 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7706#endif
Fred Drakec9680921999-12-13 16:37:25 +00007707#ifdef _SC_JOB_CONTROL
7708 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7709#endif
Fred Draked86ed291999-12-15 15:34:33 +00007710#ifdef _SC_KERN_POINTERS
7711 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7712#endif
7713#ifdef _SC_KERN_SIM
7714 {"SC_KERN_SIM", _SC_KERN_SIM},
7715#endif
Fred Drakec9680921999-12-13 16:37:25 +00007716#ifdef _SC_LINE_MAX
7717 {"SC_LINE_MAX", _SC_LINE_MAX},
7718#endif
7719#ifdef _SC_LOGIN_NAME_MAX
7720 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7721#endif
7722#ifdef _SC_LOGNAME_MAX
7723 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7724#endif
7725#ifdef _SC_LONG_BIT
7726 {"SC_LONG_BIT", _SC_LONG_BIT},
7727#endif
Fred Draked86ed291999-12-15 15:34:33 +00007728#ifdef _SC_MAC
7729 {"SC_MAC", _SC_MAC},
7730#endif
Fred Drakec9680921999-12-13 16:37:25 +00007731#ifdef _SC_MAPPED_FILES
7732 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7733#endif
7734#ifdef _SC_MAXPID
7735 {"SC_MAXPID", _SC_MAXPID},
7736#endif
7737#ifdef _SC_MB_LEN_MAX
7738 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7739#endif
7740#ifdef _SC_MEMLOCK
7741 {"SC_MEMLOCK", _SC_MEMLOCK},
7742#endif
7743#ifdef _SC_MEMLOCK_RANGE
7744 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7745#endif
7746#ifdef _SC_MEMORY_PROTECTION
7747 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7748#endif
7749#ifdef _SC_MESSAGE_PASSING
7750 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7751#endif
Fred Draked86ed291999-12-15 15:34:33 +00007752#ifdef _SC_MMAP_FIXED_ALIGNMENT
7753 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7754#endif
Fred Drakec9680921999-12-13 16:37:25 +00007755#ifdef _SC_MQ_OPEN_MAX
7756 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7757#endif
7758#ifdef _SC_MQ_PRIO_MAX
7759 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7760#endif
Fred Draked86ed291999-12-15 15:34:33 +00007761#ifdef _SC_NACLS_MAX
7762 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7763#endif
Fred Drakec9680921999-12-13 16:37:25 +00007764#ifdef _SC_NGROUPS_MAX
7765 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7766#endif
7767#ifdef _SC_NL_ARGMAX
7768 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7769#endif
7770#ifdef _SC_NL_LANGMAX
7771 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7772#endif
7773#ifdef _SC_NL_MSGMAX
7774 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7775#endif
7776#ifdef _SC_NL_NMAX
7777 {"SC_NL_NMAX", _SC_NL_NMAX},
7778#endif
7779#ifdef _SC_NL_SETMAX
7780 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7781#endif
7782#ifdef _SC_NL_TEXTMAX
7783 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7784#endif
7785#ifdef _SC_NPROCESSORS_CONF
7786 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7787#endif
7788#ifdef _SC_NPROCESSORS_ONLN
7789 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7790#endif
Fred Draked86ed291999-12-15 15:34:33 +00007791#ifdef _SC_NPROC_CONF
7792 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7793#endif
7794#ifdef _SC_NPROC_ONLN
7795 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7796#endif
Fred Drakec9680921999-12-13 16:37:25 +00007797#ifdef _SC_NZERO
7798 {"SC_NZERO", _SC_NZERO},
7799#endif
7800#ifdef _SC_OPEN_MAX
7801 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7802#endif
7803#ifdef _SC_PAGESIZE
7804 {"SC_PAGESIZE", _SC_PAGESIZE},
7805#endif
7806#ifdef _SC_PAGE_SIZE
7807 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7808#endif
7809#ifdef _SC_PASS_MAX
7810 {"SC_PASS_MAX", _SC_PASS_MAX},
7811#endif
7812#ifdef _SC_PHYS_PAGES
7813 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7814#endif
7815#ifdef _SC_PII
7816 {"SC_PII", _SC_PII},
7817#endif
7818#ifdef _SC_PII_INTERNET
7819 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7820#endif
7821#ifdef _SC_PII_INTERNET_DGRAM
7822 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7823#endif
7824#ifdef _SC_PII_INTERNET_STREAM
7825 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7826#endif
7827#ifdef _SC_PII_OSI
7828 {"SC_PII_OSI", _SC_PII_OSI},
7829#endif
7830#ifdef _SC_PII_OSI_CLTS
7831 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7832#endif
7833#ifdef _SC_PII_OSI_COTS
7834 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7835#endif
7836#ifdef _SC_PII_OSI_M
7837 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7838#endif
7839#ifdef _SC_PII_SOCKET
7840 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7841#endif
7842#ifdef _SC_PII_XTI
7843 {"SC_PII_XTI", _SC_PII_XTI},
7844#endif
7845#ifdef _SC_POLL
7846 {"SC_POLL", _SC_POLL},
7847#endif
7848#ifdef _SC_PRIORITIZED_IO
7849 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7850#endif
7851#ifdef _SC_PRIORITY_SCHEDULING
7852 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7853#endif
7854#ifdef _SC_REALTIME_SIGNALS
7855 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7856#endif
7857#ifdef _SC_RE_DUP_MAX
7858 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7859#endif
7860#ifdef _SC_RTSIG_MAX
7861 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7862#endif
7863#ifdef _SC_SAVED_IDS
7864 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7865#endif
7866#ifdef _SC_SCHAR_MAX
7867 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7868#endif
7869#ifdef _SC_SCHAR_MIN
7870 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7871#endif
7872#ifdef _SC_SELECT
7873 {"SC_SELECT", _SC_SELECT},
7874#endif
7875#ifdef _SC_SEMAPHORES
7876 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7877#endif
7878#ifdef _SC_SEM_NSEMS_MAX
7879 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7880#endif
7881#ifdef _SC_SEM_VALUE_MAX
7882 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7883#endif
7884#ifdef _SC_SHARED_MEMORY_OBJECTS
7885 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7886#endif
7887#ifdef _SC_SHRT_MAX
7888 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7889#endif
7890#ifdef _SC_SHRT_MIN
7891 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7892#endif
7893#ifdef _SC_SIGQUEUE_MAX
7894 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7895#endif
7896#ifdef _SC_SIGRT_MAX
7897 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7898#endif
7899#ifdef _SC_SIGRT_MIN
7900 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7901#endif
Fred Draked86ed291999-12-15 15:34:33 +00007902#ifdef _SC_SOFTPOWER
7903 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7904#endif
Fred Drakec9680921999-12-13 16:37:25 +00007905#ifdef _SC_SPLIT_CACHE
7906 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7907#endif
7908#ifdef _SC_SSIZE_MAX
7909 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7910#endif
7911#ifdef _SC_STACK_PROT
7912 {"SC_STACK_PROT", _SC_STACK_PROT},
7913#endif
7914#ifdef _SC_STREAM_MAX
7915 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7916#endif
7917#ifdef _SC_SYNCHRONIZED_IO
7918 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7919#endif
7920#ifdef _SC_THREADS
7921 {"SC_THREADS", _SC_THREADS},
7922#endif
7923#ifdef _SC_THREAD_ATTR_STACKADDR
7924 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7925#endif
7926#ifdef _SC_THREAD_ATTR_STACKSIZE
7927 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7928#endif
7929#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7930 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7931#endif
7932#ifdef _SC_THREAD_KEYS_MAX
7933 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7934#endif
7935#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7936 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7937#endif
7938#ifdef _SC_THREAD_PRIO_INHERIT
7939 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7940#endif
7941#ifdef _SC_THREAD_PRIO_PROTECT
7942 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7943#endif
7944#ifdef _SC_THREAD_PROCESS_SHARED
7945 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7946#endif
7947#ifdef _SC_THREAD_SAFE_FUNCTIONS
7948 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7949#endif
7950#ifdef _SC_THREAD_STACK_MIN
7951 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7952#endif
7953#ifdef _SC_THREAD_THREADS_MAX
7954 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7955#endif
7956#ifdef _SC_TIMERS
7957 {"SC_TIMERS", _SC_TIMERS},
7958#endif
7959#ifdef _SC_TIMER_MAX
7960 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7961#endif
7962#ifdef _SC_TTY_NAME_MAX
7963 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7964#endif
7965#ifdef _SC_TZNAME_MAX
7966 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7967#endif
7968#ifdef _SC_T_IOV_MAX
7969 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7970#endif
7971#ifdef _SC_UCHAR_MAX
7972 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7973#endif
7974#ifdef _SC_UINT_MAX
7975 {"SC_UINT_MAX", _SC_UINT_MAX},
7976#endif
7977#ifdef _SC_UIO_MAXIOV
7978 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7979#endif
7980#ifdef _SC_ULONG_MAX
7981 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7982#endif
7983#ifdef _SC_USHRT_MAX
7984 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7985#endif
7986#ifdef _SC_VERSION
7987 {"SC_VERSION", _SC_VERSION},
7988#endif
7989#ifdef _SC_WORD_BIT
7990 {"SC_WORD_BIT", _SC_WORD_BIT},
7991#endif
7992#ifdef _SC_XBS5_ILP32_OFF32
7993 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7994#endif
7995#ifdef _SC_XBS5_ILP32_OFFBIG
7996 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7997#endif
7998#ifdef _SC_XBS5_LP64_OFF64
7999 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
8000#endif
8001#ifdef _SC_XBS5_LPBIG_OFFBIG
8002 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
8003#endif
8004#ifdef _SC_XOPEN_CRYPT
8005 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
8006#endif
8007#ifdef _SC_XOPEN_ENH_I18N
8008 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
8009#endif
8010#ifdef _SC_XOPEN_LEGACY
8011 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
8012#endif
8013#ifdef _SC_XOPEN_REALTIME
8014 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
8015#endif
8016#ifdef _SC_XOPEN_REALTIME_THREADS
8017 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
8018#endif
8019#ifdef _SC_XOPEN_SHM
8020 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
8021#endif
8022#ifdef _SC_XOPEN_UNIX
8023 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
8024#endif
8025#ifdef _SC_XOPEN_VERSION
8026 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
8027#endif
8028#ifdef _SC_XOPEN_XCU_VERSION
8029 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
8030#endif
8031#ifdef _SC_XOPEN_XPG2
8032 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
8033#endif
8034#ifdef _SC_XOPEN_XPG3
8035 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
8036#endif
8037#ifdef _SC_XOPEN_XPG4
8038 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
8039#endif
8040};
8041
8042static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008043conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008044{
8045 return conv_confname(arg, valuep, posix_constants_sysconf,
8046 sizeof(posix_constants_sysconf)
8047 / sizeof(struct constdef));
8048}
8049
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008050PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008051"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008052Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008053
8054static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008055posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008056{
8057 PyObject *result = NULL;
8058 int name;
8059
8060 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
8061 int value;
8062
8063 errno = 0;
8064 value = sysconf(name);
8065 if (value == -1 && errno != 0)
8066 posix_error();
8067 else
8068 result = PyInt_FromLong(value);
8069 }
8070 return result;
8071}
8072#endif
8073
8074
Fred Drakebec628d1999-12-15 18:31:10 +00008075/* This code is used to ensure that the tables of configuration value names
8076 * are in sorted order as required by conv_confname(), and also to build the
8077 * the exported dictionaries that are used to publish information about the
8078 * names available on the host platform.
8079 *
8080 * Sorting the table at runtime ensures that the table is properly ordered
8081 * when used, even for platforms we're not able to test on. It also makes
8082 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008083 */
Fred Drakebec628d1999-12-15 18:31:10 +00008084
8085static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008086cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008087{
8088 const struct constdef *c1 =
8089 (const struct constdef *) v1;
8090 const struct constdef *c2 =
8091 (const struct constdef *) v2;
8092
8093 return strcmp(c1->name, c2->name);
8094}
8095
8096static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008097setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008098 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008099{
Fred Drakebec628d1999-12-15 18:31:10 +00008100 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008101 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008102
8103 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8104 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008105 if (d == NULL)
8106 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008107
Barry Warsaw3155db32000-04-13 15:20:40 +00008108 for (i=0; i < tablesize; ++i) {
8109 PyObject *o = PyInt_FromLong(table[i].value);
8110 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8111 Py_XDECREF(o);
8112 Py_DECREF(d);
8113 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008114 }
Barry Warsaw3155db32000-04-13 15:20:40 +00008115 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008116 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008117 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008118}
8119
Fred Drakebec628d1999-12-15 18:31:10 +00008120/* Return -1 on failure, 0 on success. */
8121static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008122setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008123{
8124#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008125 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008126 sizeof(posix_constants_pathconf)
8127 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008128 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008129 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008130#endif
8131#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008132 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008133 sizeof(posix_constants_confstr)
8134 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008135 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008136 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008137#endif
8138#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008139 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008140 sizeof(posix_constants_sysconf)
8141 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008142 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00008143 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008144#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008145 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008146}
Fred Draked86ed291999-12-15 15:34:33 +00008147
8148
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008149PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008150"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008151Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008152in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008153
8154static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008155posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008156{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008157 abort();
8158 /*NOTREACHED*/
8159 Py_FatalError("abort() called from Python code didn't abort!");
8160 return NULL;
8161}
Fred Drakebec628d1999-12-15 18:31:10 +00008162
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008163#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008164PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008165"startfile(filepath [, operation]) - Start a file with its associated\n\
8166application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008167\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008168When \"operation\" is not specified or \"open\", this acts like\n\
8169double-clicking the file in Explorer, or giving the file name as an\n\
8170argument to the DOS \"start\" command: the file is opened with whatever\n\
8171application (if any) its extension is associated.\n\
8172When another \"operation\" is given, it specifies what should be done with\n\
8173the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008174\n\
8175startfile returns as soon as the associated application is launched.\n\
8176There is no option to wait for the application to close, and no way\n\
8177to retrieve the application's exit status.\n\
8178\n\
8179The filepath is relative to the current directory. If you want to use\n\
8180an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008181the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008182
8183static PyObject *
8184win32_startfile(PyObject *self, PyObject *args)
8185{
8186 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00008187 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008188 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00008189#ifdef Py_WIN_WIDE_FILENAMES
8190 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008191 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00008192 if (!PyArg_ParseTuple(args, "U|s:startfile",
8193 &unipath, &operation)) {
8194 PyErr_Clear();
8195 goto normal;
8196 }
8197
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008198
8199 if (operation) {
8200 woperation = PyUnicode_DecodeASCII(operation,
8201 strlen(operation), NULL);
8202 if (!woperation) {
8203 PyErr_Clear();
8204 operation = NULL;
8205 goto normal;
8206 }
Georg Brandlad89dc82006-04-03 12:26:26 +00008207 }
8208
8209 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008210 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00008211 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00008212 NULL, NULL, SW_SHOWNORMAL);
8213 Py_END_ALLOW_THREADS
8214
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008215 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00008216 if (rc <= (HINSTANCE)32) {
8217 PyObject *errval = win32_error_unicode("startfile",
8218 PyUnicode_AS_UNICODE(unipath));
8219 return errval;
8220 }
8221 Py_INCREF(Py_None);
8222 return Py_None;
8223 }
8224#endif
8225
8226normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00008227 if (!PyArg_ParseTuple(args, "et|s:startfile",
8228 Py_FileSystemDefaultEncoding, &filepath,
8229 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00008230 return NULL;
8231 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00008232 rc = ShellExecute((HWND)0, operation, filepath,
8233 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008234 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00008235 if (rc <= (HINSTANCE)32) {
8236 PyObject *errval = win32_error("startfile", filepath);
8237 PyMem_Free(filepath);
8238 return errval;
8239 }
8240 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008241 Py_INCREF(Py_None);
8242 return Py_None;
8243}
8244#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008245
Martin v. Löwis438b5342002-12-27 10:16:42 +00008246#ifdef HAVE_GETLOADAVG
8247PyDoc_STRVAR(posix_getloadavg__doc__,
8248"getloadavg() -> (float, float, float)\n\n\
8249Return the number of processes in the system run queue averaged over\n\
8250the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8251was unobtainable");
8252
8253static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008254posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008255{
8256 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008257 if (getloadavg(loadavg, 3)!=3) {
8258 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8259 return NULL;
8260 } else
8261 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8262}
8263#endif
8264
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008265#ifdef MS_WINDOWS
8266
8267PyDoc_STRVAR(win32_urandom__doc__,
8268"urandom(n) -> str\n\n\
8269Return a string of n random bytes suitable for cryptographic use.");
8270
8271typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8272 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8273 DWORD dwFlags );
8274typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8275 BYTE *pbBuffer );
8276
8277static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008278/* This handle is never explicitly released. Instead, the operating
8279 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008280static HCRYPTPROV hCryptProv = 0;
8281
Tim Peters4ad82172004-08-30 17:02:04 +00008282static PyObject*
8283win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008284{
Tim Petersd3115382004-08-30 17:36:46 +00008285 int howMany;
8286 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008287
Tim Peters4ad82172004-08-30 17:02:04 +00008288 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00008289 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00008290 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00008291 if (howMany < 0)
8292 return PyErr_Format(PyExc_ValueError,
8293 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008294
Tim Peters4ad82172004-08-30 17:02:04 +00008295 if (hCryptProv == 0) {
8296 HINSTANCE hAdvAPI32 = NULL;
8297 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008298
Tim Peters4ad82172004-08-30 17:02:04 +00008299 /* Obtain handle to the DLL containing CryptoAPI
8300 This should not fail */
8301 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8302 if(hAdvAPI32 == NULL)
8303 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008304
Tim Peters4ad82172004-08-30 17:02:04 +00008305 /* Obtain pointers to the CryptoAPI functions
8306 This will fail on some early versions of Win95 */
8307 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8308 hAdvAPI32,
8309 "CryptAcquireContextA");
8310 if (pCryptAcquireContext == NULL)
8311 return PyErr_Format(PyExc_NotImplementedError,
8312 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008313
Tim Peters4ad82172004-08-30 17:02:04 +00008314 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8315 hAdvAPI32, "CryptGenRandom");
Georg Brandl74bb7832006-09-06 06:03:59 +00008316 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00008317 return PyErr_Format(PyExc_NotImplementedError,
8318 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008319
Tim Peters4ad82172004-08-30 17:02:04 +00008320 /* Acquire context */
8321 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8322 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8323 return win32_error("CryptAcquireContext", NULL);
8324 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008325
Tim Peters4ad82172004-08-30 17:02:04 +00008326 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008327 result = PyString_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00008328 if (result != NULL) {
8329 /* Get random data */
Amaury Forgeot d'Arc74bd40d2008-07-21 21:06:46 +00008330 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00008331 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008332 PyString_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00008333 Py_DECREF(result);
8334 return win32_error("CryptGenRandom", NULL);
8335 }
Tim Peters4ad82172004-08-30 17:02:04 +00008336 }
Tim Petersd3115382004-08-30 17:36:46 +00008337 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008338}
8339#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008340
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008341#ifdef __VMS
8342/* Use openssl random routine */
8343#include <openssl/rand.h>
8344PyDoc_STRVAR(vms_urandom__doc__,
8345"urandom(n) -> str\n\n\
8346Return a string of n random bytes suitable for cryptographic use.");
8347
8348static PyObject*
8349vms_urandom(PyObject *self, PyObject *args)
8350{
8351 int howMany;
8352 PyObject* result;
8353
8354 /* Read arguments */
8355 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8356 return NULL;
8357 if (howMany < 0)
8358 return PyErr_Format(PyExc_ValueError,
8359 "negative argument not allowed");
8360
8361 /* Allocate bytes */
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008362 result = PyString_FromStringAndSize(NULL, howMany);
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008363 if (result != NULL) {
8364 /* Get random data */
8365 if (RAND_pseudo_bytes((unsigned char*)
Gregory P. Smithdd96db62008-06-09 04:58:54 +00008366 PyString_AS_STRING(result),
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008367 howMany) < 0) {
8368 Py_DECREF(result);
8369 return PyErr_Format(PyExc_ValueError,
8370 "RAND_pseudo_bytes");
8371 }
8372 }
8373 return result;
8374}
8375#endif
8376
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008377static PyMethodDef posix_methods[] = {
8378 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8379#ifdef HAVE_TTYNAME
8380 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8381#endif
8382 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008383#ifdef HAVE_CHFLAGS
8384 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8385#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008386 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008387#ifdef HAVE_FCHMOD
8388 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8389#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008390#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008391 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008392#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008393#ifdef HAVE_LCHMOD
8394 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8395#endif /* HAVE_LCHMOD */
8396#ifdef HAVE_FCHOWN
8397 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8398#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008399#ifdef HAVE_LCHFLAGS
8400 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8401#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008402#ifdef HAVE_LCHOWN
8403 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8404#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008405#ifdef HAVE_CHROOT
8406 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8407#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008408#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00008409 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008410#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008411#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00008412 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008413#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00008414 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008415#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008416#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008417#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008418 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008419#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008420 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8421 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8422 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008423#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008424 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008425#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008426#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008427 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008428#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008429 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8430 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8431 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008432 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008433#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008434 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008435#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008436#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008437 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008438#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008439 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008440#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00008441 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008442#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008443 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8444 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8445 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008446#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00008447 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008448#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008449 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008450#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008451 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8452 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008453#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008454#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008455 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8456 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008457#if defined(PYOS_OS2)
8458 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8459 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8460#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008461#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008462#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008463 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008464#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008465#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008466 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008467#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008468#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008469 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008470#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008471#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008472 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008473#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008474#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008475 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008476#endif /* HAVE_GETEGID */
8477#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008478 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008479#endif /* HAVE_GETEUID */
8480#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008481 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008482#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008483#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008484 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008485#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008486 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008487#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008488 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008489#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008490#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008491 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008492#endif /* HAVE_GETPPID */
8493#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008494 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008495#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008496#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008497 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008498#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008499#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008500 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008501#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008502#ifdef HAVE_KILLPG
8503 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8504#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008505#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008506 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008507#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008508#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008509 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008510#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008511 {"popen2", win32_popen2, METH_VARARGS},
8512 {"popen3", win32_popen3, METH_VARARGS},
8513 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008514 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008515#else
8516#if defined(PYOS_OS2) && defined(PYCC_GCC)
8517 {"popen2", os2emx_popen2, METH_VARARGS},
8518 {"popen3", os2emx_popen3, METH_VARARGS},
8519 {"popen4", os2emx_popen4, METH_VARARGS},
8520#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008521#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008522#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008523#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008524 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008525#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008526#ifdef HAVE_SETEUID
8527 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8528#endif /* HAVE_SETEUID */
8529#ifdef HAVE_SETEGID
8530 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8531#endif /* HAVE_SETEGID */
8532#ifdef HAVE_SETREUID
8533 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8534#endif /* HAVE_SETREUID */
8535#ifdef HAVE_SETREGID
8536 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8537#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008538#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008539 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008540#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008541#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008542 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008543#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008544#ifdef HAVE_GETPGID
8545 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8546#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008547#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008548 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008549#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008550#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008551 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008552#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008553#ifdef HAVE_WAIT3
8554 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8555#endif /* HAVE_WAIT3 */
8556#ifdef HAVE_WAIT4
8557 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8558#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008559#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008560 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008561#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008562#ifdef HAVE_GETSID
8563 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8564#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008565#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008566 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008567#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008568#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008569 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008570#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008571#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008572 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008573#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008574#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008575 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008576#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008577 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8578 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Georg Brandl309501a2008-01-19 20:22:13 +00008579 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008580 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8581 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8582 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8583 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8584 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8585 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8586 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008587 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008588#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008589 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008590#endif
8591#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008592 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008593#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008594#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008595 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8596#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008597#ifdef HAVE_DEVICE_MACROS
8598 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8599 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8600 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8601#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008602#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008603 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008604#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008605#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008606 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008607#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008608#ifdef HAVE_UNSETENV
8609 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8610#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008611 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008612#ifdef HAVE_FCHDIR
8613 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8614#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008615#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008616 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008617#endif
8618#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008619 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008620#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008621#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008622#ifdef WCOREDUMP
8623 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8624#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008625#ifdef WIFCONTINUED
8626 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8627#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008628#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008629 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008630#endif /* WIFSTOPPED */
8631#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008632 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008633#endif /* WIFSIGNALED */
8634#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008635 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008636#endif /* WIFEXITED */
8637#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008638 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008639#endif /* WEXITSTATUS */
8640#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008641 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008642#endif /* WTERMSIG */
8643#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008644 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008645#endif /* WSTOPSIG */
8646#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008647#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008648 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008649#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008650#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008651 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008652#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008653#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008654 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008655#endif
8656#ifdef HAVE_TEMPNAM
8657 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8658#endif
8659#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008660 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008661#endif
Fred Drakec9680921999-12-13 16:37:25 +00008662#ifdef HAVE_CONFSTR
8663 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8664#endif
8665#ifdef HAVE_SYSCONF
8666 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8667#endif
8668#ifdef HAVE_FPATHCONF
8669 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8670#endif
8671#ifdef HAVE_PATHCONF
8672 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8673#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008674 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008675#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008676 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8677#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008678#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008679 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008680#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008681 #ifdef MS_WINDOWS
8682 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8683 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008684 #ifdef __VMS
8685 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8686 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008687 {NULL, NULL} /* Sentinel */
8688};
8689
8690
Barry Warsaw4a342091996-12-19 23:50:02 +00008691static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008692ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008693{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008694 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008695}
8696
Guido van Rossumd48f2521997-12-05 22:19:34 +00008697#if defined(PYOS_OS2)
8698/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008699static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008700{
8701 APIRET rc;
8702 ULONG values[QSV_MAX+1];
8703 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008704 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008705
8706 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008707 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008708 Py_END_ALLOW_THREADS
8709
8710 if (rc != NO_ERROR) {
8711 os2_error(rc);
8712 return -1;
8713 }
8714
Fred Drake4d1e64b2002-04-15 19:40:07 +00008715 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8716 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8717 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8718 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8719 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8720 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8721 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008722
8723 switch (values[QSV_VERSION_MINOR]) {
8724 case 0: ver = "2.00"; break;
8725 case 10: ver = "2.10"; break;
8726 case 11: ver = "2.11"; break;
8727 case 30: ver = "3.00"; break;
8728 case 40: ver = "4.00"; break;
8729 case 50: ver = "5.00"; break;
8730 default:
Tim Peters885d4572001-11-28 20:27:42 +00008731 PyOS_snprintf(tmp, sizeof(tmp),
8732 "%d-%d", values[QSV_VERSION_MAJOR],
8733 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008734 ver = &tmp[0];
8735 }
8736
8737 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008738 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008739 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008740
8741 /* Add Indicator of Which Drive was Used to Boot the System */
8742 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8743 tmp[1] = ':';
8744 tmp[2] = '\0';
8745
Fred Drake4d1e64b2002-04-15 19:40:07 +00008746 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008747}
8748#endif
8749
Barry Warsaw4a342091996-12-19 23:50:02 +00008750static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008751all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008752{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008753#ifdef F_OK
8754 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008755#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008756#ifdef R_OK
8757 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008758#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008759#ifdef W_OK
8760 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008761#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008762#ifdef X_OK
8763 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008764#endif
Fred Drakec9680921999-12-13 16:37:25 +00008765#ifdef NGROUPS_MAX
8766 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8767#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008768#ifdef TMP_MAX
8769 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8770#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008771#ifdef WCONTINUED
8772 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8773#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008774#ifdef WNOHANG
8775 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008776#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008777#ifdef WUNTRACED
8778 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8779#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008780#ifdef O_RDONLY
8781 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8782#endif
8783#ifdef O_WRONLY
8784 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8785#endif
8786#ifdef O_RDWR
8787 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8788#endif
8789#ifdef O_NDELAY
8790 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8791#endif
8792#ifdef O_NONBLOCK
8793 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8794#endif
8795#ifdef O_APPEND
8796 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8797#endif
8798#ifdef O_DSYNC
8799 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8800#endif
8801#ifdef O_RSYNC
8802 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8803#endif
8804#ifdef O_SYNC
8805 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8806#endif
8807#ifdef O_NOCTTY
8808 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8809#endif
8810#ifdef O_CREAT
8811 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8812#endif
8813#ifdef O_EXCL
8814 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8815#endif
8816#ifdef O_TRUNC
8817 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8818#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008819#ifdef O_BINARY
8820 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8821#endif
8822#ifdef O_TEXT
8823 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8824#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008825#ifdef O_LARGEFILE
8826 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8827#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008828#ifdef O_SHLOCK
8829 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8830#endif
8831#ifdef O_EXLOCK
8832 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8833#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008834
Tim Peters5aa91602002-01-30 05:46:57 +00008835/* MS Windows */
8836#ifdef O_NOINHERIT
8837 /* Don't inherit in child processes. */
8838 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8839#endif
8840#ifdef _O_SHORT_LIVED
8841 /* Optimize for short life (keep in memory). */
8842 /* MS forgot to define this one with a non-underscore form too. */
8843 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8844#endif
8845#ifdef O_TEMPORARY
8846 /* Automatically delete when last handle is closed. */
8847 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8848#endif
8849#ifdef O_RANDOM
8850 /* Optimize for random access. */
8851 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8852#endif
8853#ifdef O_SEQUENTIAL
8854 /* Optimize for sequential access. */
8855 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8856#endif
8857
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008858/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00008859#ifdef O_ASYNC
8860 /* Send a SIGIO signal whenever input or output
8861 becomes available on file descriptor */
8862 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8863#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008864#ifdef O_DIRECT
8865 /* Direct disk access. */
8866 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8867#endif
8868#ifdef O_DIRECTORY
8869 /* Must be a directory. */
8870 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8871#endif
8872#ifdef O_NOFOLLOW
8873 /* Do not follow links. */
8874 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8875#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00008876#ifdef O_NOATIME
8877 /* Do not update the access time. */
8878 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8879#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008880
Barry Warsaw5676bd12003-01-07 20:57:09 +00008881 /* These come from sysexits.h */
8882#ifdef EX_OK
8883 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008884#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008885#ifdef EX_USAGE
8886 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008887#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008888#ifdef EX_DATAERR
8889 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008890#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008891#ifdef EX_NOINPUT
8892 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008893#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008894#ifdef EX_NOUSER
8895 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008896#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008897#ifdef EX_NOHOST
8898 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008899#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008900#ifdef EX_UNAVAILABLE
8901 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008902#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008903#ifdef EX_SOFTWARE
8904 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008905#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008906#ifdef EX_OSERR
8907 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008908#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008909#ifdef EX_OSFILE
8910 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008911#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008912#ifdef EX_CANTCREAT
8913 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008914#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008915#ifdef EX_IOERR
8916 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008917#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008918#ifdef EX_TEMPFAIL
8919 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008920#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008921#ifdef EX_PROTOCOL
8922 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008923#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008924#ifdef EX_NOPERM
8925 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008926#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008927#ifdef EX_CONFIG
8928 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008929#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008930#ifdef EX_NOTFOUND
8931 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008932#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008933
Guido van Rossum246bc171999-02-01 23:54:31 +00008934#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008935#if defined(PYOS_OS2) && defined(PYCC_GCC)
8936 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8937 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8938 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8939 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8940 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8941 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8942 if (ins(d, "P_PM", (long)P_PM)) return -1;
8943 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8944 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8945 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8946 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8947 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8948 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8949 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8950 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8951 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8952 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8953 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8954 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8955 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8956#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008957 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8958 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8959 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8960 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8961 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008962#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008963#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008964
Guido van Rossumd48f2521997-12-05 22:19:34 +00008965#if defined(PYOS_OS2)
8966 if (insertvalues(d)) return -1;
8967#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008968 return 0;
8969}
8970
8971
Tim Peters5aa91602002-01-30 05:46:57 +00008972#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008973#define INITFUNC initnt
8974#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008975
8976#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008977#define INITFUNC initos2
8978#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008979
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008980#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008981#define INITFUNC initposix
8982#define MODNAME "posix"
8983#endif
8984
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008985PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008986INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008987{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008988 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008989
Fred Drake4d1e64b2002-04-15 19:40:07 +00008990 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008991 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008992 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008993 if (m == NULL)
8994 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008995
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008996 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008997 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008998 Py_XINCREF(v);
8999 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009000 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00009001 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009002
Fred Drake4d1e64b2002-04-15 19:40:07 +00009003 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00009004 return;
9005
Fred Drake4d1e64b2002-04-15 19:40:07 +00009006 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00009007 return;
9008
Fred Drake4d1e64b2002-04-15 19:40:07 +00009009 Py_INCREF(PyExc_OSError);
9010 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009011
Guido van Rossumb3d39562000-01-31 18:41:26 +00009012#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00009013 if (posix_putenv_garbage == NULL)
9014 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009015#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009016
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009017 if (!initialized) {
9018 stat_result_desc.name = MODNAME ".stat_result";
9019 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9020 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9021 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9022 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9023 structseq_new = StatResultType.tp_new;
9024 StatResultType.tp_new = statresult_new;
9025
9026 statvfs_result_desc.name = MODNAME ".statvfs_result";
9027 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis3f15ae32008-12-29 18:20:48 +00009028#ifdef NEED_TICKS_PER_SECOND
9029# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
9030 ticks_per_second = sysconf(_SC_CLK_TCK);
9031# elif defined(HZ)
9032 ticks_per_second = HZ;
9033# else
9034 ticks_per_second = 60; /* magic fallback value; may be bogus */
9035# endif
9036#endif
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009037 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00009038 Py_INCREF((PyObject*) &StatResultType);
9039 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00009040 Py_INCREF((PyObject*) &StatVFSResultType);
9041 PyModule_AddObject(m, "statvfs_result",
9042 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009043 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009044
9045#ifdef __APPLE__
9046 /*
9047 * Step 2 of weak-linking support on Mac OS X.
9048 *
9049 * The code below removes functions that are not available on the
9050 * currently active platform.
9051 *
9052 * This block allow one to use a python binary that was build on
9053 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9054 * OSX 10.4.
9055 */
9056#ifdef HAVE_FSTATVFS
9057 if (fstatvfs == NULL) {
9058 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9059 return;
9060 }
9061 }
9062#endif /* HAVE_FSTATVFS */
9063
9064#ifdef HAVE_STATVFS
9065 if (statvfs == NULL) {
9066 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9067 return;
9068 }
9069 }
9070#endif /* HAVE_STATVFS */
9071
9072# ifdef HAVE_LCHOWN
9073 if (lchown == NULL) {
9074 if (PyObject_DelAttrString(m, "lchown") == -1) {
9075 return;
9076 }
9077 }
9078#endif /* HAVE_LCHOWN */
9079
9080
9081#endif /* __APPLE__ */
9082
Guido van Rossumb6775db1994-08-01 11:34:53 +00009083}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009084
9085#ifdef __cplusplus
9086}
9087#endif
9088
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009089