blob: 12b34726c2185baeafd336862e3530b63440563a [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
Thomas Wouters477c8d52006-05-27 19:21:47 +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
Thomas Wouters49fd7fa2006-04-21 10:40:58 +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
Thomas Wouters0e3f5912006-08-11 14:57:12 +000067#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +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>
Thomas Wouters0e3f5912006-08-11 14:57:12 +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
Thomas Wouters0e3f5912006-08-11 14:57:12 +000079#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000080#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000081#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000082
Guido van Rossumb6775db1994-08-01 11:34:53 +000083#ifdef HAVE_FCNTL_H
84#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000085#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000086
Guido van Rossuma6535fd2001-10-18 19:44:10 +000087#ifdef HAVE_GRP_H
88#include <grp.h>
89#endif
90
Barry Warsaw5676bd12003-01-07 20:57:09 +000091#ifdef HAVE_SYSEXITS_H
92#include <sysexits.h>
93#endif /* HAVE_SYSEXITS_H */
94
Anthony Baxter8a560de2004-10-13 15:30:56 +000095#ifdef HAVE_SYS_LOADAVG_H
96#include <sys/loadavg.h>
97#endif
98
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000100/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#include <process.h>
103#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000104#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#define HAVE_GETCWD 1
106#define HAVE_OPENDIR 1
107#define HAVE_SYSTEM 1
108#if defined(__OS2__)
109#define HAVE_EXECV 1
110#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#include <process.h>
113#else
114#ifdef __BORLANDC__ /* Borland compiler */
115#define HAVE_EXECV 1
116#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_OPENDIR 1
118#define HAVE_PIPE 1
119#define HAVE_POPEN 1
120#define HAVE_SYSTEM 1
121#define HAVE_WAIT 1
122#else
123#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000124#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000125#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000126#define HAVE_EXECV 1
127#define HAVE_PIPE 1
128#define HAVE_POPEN 1
129#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000130#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000131#define HAVE_FSYNC 1
132#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000133#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000134#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
135/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136#else /* all other compilers */
137/* Unix functions that the configure script doesn't check for */
138#define HAVE_EXECV 1
139#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000140#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
141#define HAVE_FORK1 1
142#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#define HAVE_GETCWD 1
144#define HAVE_GETEGID 1
145#define HAVE_GETEUID 1
146#define HAVE_GETGID 1
147#define HAVE_GETPPID 1
148#define HAVE_GETUID 1
149#define HAVE_KILL 1
150#define HAVE_OPENDIR 1
151#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000152#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000154#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#define HAVE_SYSTEM 1
156#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000157#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000158#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#endif /* _MSC_VER */
160#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000161#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000162#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000163
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000164#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000165
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000166#if defined(__sgi)&&_COMPILER_VERSION>=700
167/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
168 (default) */
169extern char *ctermid_r(char *);
170#endif
171
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000172#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000173#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000175#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000176#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000177extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000179extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000180#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000181#endif
182#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000183extern int chdir(char *);
184extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000185#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000186extern int chdir(const char *);
187extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000188#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000189#ifdef __BORLANDC__
190extern int chmod(const char *, int);
191#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000192extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000193#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000194extern int chown(const char *, uid_t, gid_t);
195extern char *getcwd(char *, int);
196extern char *strerror(int);
197extern int link(const char *, const char *);
198extern int rename(const char *, const char *);
199extern int stat(const char *, struct stat *);
200extern int unlink(const char *);
201extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000204#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000207#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000209
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000210#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#ifdef HAVE_UTIME_H
213#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000214#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000216#ifdef HAVE_SYS_UTIME_H
217#include <sys/utime.h>
218#define HAVE_UTIME_H /* pretend we do for the rest of this file */
219#endif /* HAVE_SYS_UTIME_H */
220
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#ifdef HAVE_SYS_TIMES_H
222#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000223#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
225#ifdef HAVE_SYS_PARAM_H
226#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000227#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228
229#ifdef HAVE_SYS_UTSNAME_H
230#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000231#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000233#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#define NAMLEN(dirent) strlen((dirent)->d_name)
236#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000237#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#include <direct.h>
239#define NAMLEN(dirent) strlen((dirent)->d_name)
240#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000243#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#endif
247#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000249#endif
250#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000252#endif
253#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000255#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000256#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000258#endif
259#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000261#endif
262#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000264#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000265#include "osdefs.h"
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000266#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000268#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000269#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000270#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000271#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272
Guido van Rossumd48f2521997-12-05 22:19:34 +0000273#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000275#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276
Tim Petersbc2e10e2002-03-03 23:17:02 +0000277#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000278#if defined(PATH_MAX) && PATH_MAX > 1024
279#define MAXPATHLEN PATH_MAX
280#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000281#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000282#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000283#endif /* MAXPATHLEN */
284
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000285#ifdef UNION_WAIT
286/* Emulate some macros on systems that have a union instead of macros */
287
288#ifndef WIFEXITED
289#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
290#endif
291
292#ifndef WEXITSTATUS
293#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
294#endif
295
296#ifndef WTERMSIG
297#define WTERMSIG(u_wait) ((u_wait).w_termsig)
298#endif
299
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000300#define WAIT_TYPE union wait
301#define WAIT_STATUS_INT(s) (s.w_status)
302
303#else /* !UNION_WAIT */
304#define WAIT_TYPE int
305#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000306#endif /* UNION_WAIT */
307
Greg Wardb48bc172000-03-01 21:51:56 +0000308/* Don't use the "_r" form if we don't need it (also, won't have a
309 prototype for it, at least on Solaris -- maybe others as well?). */
310#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
311#define USE_CTERMID_R
312#endif
313
314#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
315#define USE_TMPNAM_R
316#endif
317
Fred Drake699f3522000-06-29 21:12:41 +0000318/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000319#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000320#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000321# define STAT win32_stat
322# define FSTAT win32_fstat
323# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000324#else
325# define STAT stat
326# define FSTAT fstat
327# define STRUCT_STAT struct stat
328#endif
329
Tim Peters11b23062003-04-23 02:39:17 +0000330#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000331#include <sys/mkdev.h>
332#else
333#if defined(MAJOR_IN_SYSMACROS)
334#include <sys/sysmacros.h>
335#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000336#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
337#include <sys/mkdev.h>
338#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000339#endif
Fred Drake699f3522000-06-29 21:12:41 +0000340
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000342#ifdef WITH_NEXT_FRAMEWORK
343/* On Darwin/MacOSX a shared library or framework has no access to
344** environ directly, we must obtain it with _NSGetEnviron().
345*/
346#include <crt_externs.h>
347static char **environ;
348#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000350#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000351
Barry Warsaw53699e91996-12-10 23:23:01 +0000352static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000353convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354{
Barry Warsaw53699e91996-12-10 23:23:01 +0000355 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000356 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000357 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000358 if (d == NULL)
359 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000360#ifdef WITH_NEXT_FRAMEWORK
361 if (environ == NULL)
362 environ = *_NSGetEnviron();
363#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000364 if (environ == NULL)
365 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000366 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000367 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000368 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000369 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000370 char *p = strchr(*e, '=');
371 if (p == NULL)
372 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000373 k = PyString_FromStringAndSize(*e, (int)(p-*e));
374 if (k == NULL) {
375 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000376 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000377 }
378 v = PyString_FromString(p+1);
379 if (v == NULL) {
380 PyErr_Clear();
381 Py_DECREF(k);
382 continue;
383 }
384 if (PyDict_GetItem(d, k) == NULL) {
385 if (PyDict_SetItem(d, k, v) != 0)
386 PyErr_Clear();
387 }
388 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000389 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000390 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000391#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000392 {
393 APIRET rc;
394 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
395
396 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000397 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000398 PyObject *v = PyString_FromString(buffer);
399 PyDict_SetItemString(d, "BEGINLIBPATH", v);
400 Py_DECREF(v);
401 }
402 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
403 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
404 PyObject *v = PyString_FromString(buffer);
405 PyDict_SetItemString(d, "ENDLIBPATH", v);
406 Py_DECREF(v);
407 }
408 }
409#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000410 return d;
411}
412
413
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000414/* Set a POSIX-specific error from errno, and return NULL */
415
Barry Warsawd58d7641998-07-23 16:14:40 +0000416static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000417posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000418{
Barry Warsawca74da41999-02-09 19:31:45 +0000419 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000420}
Barry Warsawd58d7641998-07-23 16:14:40 +0000421static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000422posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000423{
Barry Warsawca74da41999-02-09 19:31:45 +0000424 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000425}
426
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000427#ifdef Py_WIN_WIDE_FILENAMES
428static PyObject *
429posix_error_with_unicode_filename(Py_UNICODE* name)
430{
431 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
432}
433#endif /* Py_WIN_WIDE_FILENAMES */
434
435
Mark Hammondef8b6542001-05-13 08:04:26 +0000436static PyObject *
437posix_error_with_allocated_filename(char* name)
438{
439 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
440 PyMem_Free(name);
441 return rc;
442}
443
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000444#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000445static PyObject *
446win32_error(char* function, char* filename)
447{
Mark Hammond33a6da92000-08-15 00:46:38 +0000448 /* XXX We should pass the function name along in the future.
449 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000450 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000451 Windows error object, which is non-trivial.
452 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000453 errno = GetLastError();
454 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000455 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000456 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000457 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000458}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000459
460#ifdef Py_WIN_WIDE_FILENAMES
461static PyObject *
462win32_error_unicode(char* function, Py_UNICODE* filename)
463{
464 /* XXX - see win32_error for comments on 'function' */
465 errno = GetLastError();
466 if (filename)
467 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
468 else
469 return PyErr_SetFromWindowsErr(errno);
470}
471
472static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
473{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000474}
475
476/* Function suitable for O& conversion */
477static int
478convert_to_unicode(PyObject *arg, void* _param)
479{
480 PyObject **param = (PyObject**)_param;
481 if (PyUnicode_CheckExact(arg)) {
482 Py_INCREF(arg);
483 *param = arg;
484 }
485 else if (PyUnicode_Check(arg)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000486 /* For a Unicode subtype that's not a Unicode object,
487 return a true Unicode object with the same data. */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000488 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
489 PyUnicode_GET_SIZE(arg));
490 return *param != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000491 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000492 else
493 *param = PyUnicode_FromEncodedObject(arg,
494 Py_FileSystemDefaultEncoding,
495 "strict");
496 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000497}
498
499#endif /* Py_WIN_WIDE_FILENAMES */
500
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000501#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502
Guido van Rossumd48f2521997-12-05 22:19:34 +0000503#if defined(PYOS_OS2)
504/**********************************************************************
505 * Helper Function to Trim and Format OS/2 Messages
506 **********************************************************************/
507 static void
508os2_formatmsg(char *msgbuf, int msglen, char *reason)
509{
510 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
511
512 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
513 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
514
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000515 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000516 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
517 }
518
519 /* Add Optional Reason Text */
520 if (reason) {
521 strcat(msgbuf, " : ");
522 strcat(msgbuf, reason);
523 }
524}
525
526/**********************************************************************
527 * Decode an OS/2 Operating System Error Code
528 *
529 * A convenience function to lookup an OS/2 error code and return a
530 * text message we can use to raise a Python exception.
531 *
532 * Notes:
533 * The messages for errors returned from the OS/2 kernel reside in
534 * the file OSO001.MSG in the \OS2 directory hierarchy.
535 *
536 **********************************************************************/
537 static char *
538os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
539{
540 APIRET rc;
541 ULONG msglen;
542
543 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
544 Py_BEGIN_ALLOW_THREADS
545 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
546 errorcode, "oso001.msg", &msglen);
547 Py_END_ALLOW_THREADS
548
549 if (rc == NO_ERROR)
550 os2_formatmsg(msgbuf, msglen, reason);
551 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000552 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000553 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000554
555 return msgbuf;
556}
557
558/* Set an OS/2-specific error and return NULL. OS/2 kernel
559 errors are not in a global variable e.g. 'errno' nor are
560 they congruent with posix error numbers. */
561
562static PyObject * os2_error(int code)
563{
564 char text[1024];
565 PyObject *v;
566
567 os2_strerror(text, sizeof(text), code, "");
568
569 v = Py_BuildValue("(is)", code, text);
570 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000571 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000572 Py_DECREF(v);
573 }
574 return NULL; /* Signal to Python that an Exception is Pending */
575}
576
577#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000578
579/* POSIX generic methods */
580
Barry Warsaw53699e91996-12-10 23:23:01 +0000581static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000582posix_fildes(PyObject *fdobj, int (*func)(int))
583{
584 int fd;
585 int res;
586 fd = PyObject_AsFileDescriptor(fdobj);
587 if (fd < 0)
588 return NULL;
589 Py_BEGIN_ALLOW_THREADS
590 res = (*func)(fd);
591 Py_END_ALLOW_THREADS
592 if (res < 0)
593 return posix_error();
594 Py_INCREF(Py_None);
595 return Py_None;
596}
Guido van Rossum21142a01999-01-08 21:05:37 +0000597
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000598#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000599static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000600unicode_file_names(void)
601{
602 static int canusewide = -1;
603 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000604 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000605 the Windows NT family. */
606 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
607 }
608 return canusewide;
609}
610#endif
Tim Peters11b23062003-04-23 02:39:17 +0000611
Guido van Rossum21142a01999-01-08 21:05:37 +0000612static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000613posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000614{
Mark Hammondef8b6542001-05-13 08:04:26 +0000615 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000616 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000617 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000618 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000619 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000620 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000621 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000622 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000623 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000624 return posix_error_with_allocated_filename(path1);
625 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000626 Py_INCREF(Py_None);
627 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000628}
629
Barry Warsaw53699e91996-12-10 23:23:01 +0000630static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000631posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000632 char *format,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000633 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000634{
Mark Hammondef8b6542001-05-13 08:04:26 +0000635 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000636 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000637 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000638 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000639 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000640 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000641 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000642 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000643 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000644 PyMem_Free(path1);
645 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000646 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000647 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000648 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000649 Py_INCREF(Py_None);
650 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000651}
652
Thomas Wouters477c8d52006-05-27 19:21:47 +0000653#ifdef Py_WIN_WIDE_FILENAMES
654static PyObject*
655win32_1str(PyObject* args, char* func,
656 char* format, BOOL (__stdcall *funcA)(LPCSTR),
657 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
658{
659 PyObject *uni;
660 char *ansi;
661 BOOL result;
662 if (unicode_file_names()) {
663 if (!PyArg_ParseTuple(args, wformat, &uni))
664 PyErr_Clear();
665 else {
666 Py_BEGIN_ALLOW_THREADS
667 result = funcW(PyUnicode_AsUnicode(uni));
668 Py_END_ALLOW_THREADS
669 if (!result)
670 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
671 Py_INCREF(Py_None);
672 return Py_None;
673 }
674 }
675 if (!PyArg_ParseTuple(args, format, &ansi))
676 return NULL;
677 Py_BEGIN_ALLOW_THREADS
678 result = funcA(ansi);
679 Py_END_ALLOW_THREADS
680 if (!result)
681 return win32_error(func, ansi);
682 Py_INCREF(Py_None);
683 return Py_None;
684
685}
686
687/* This is a reimplementation of the C library's chdir function,
688 but one that produces Win32 errors instead of DOS error codes.
689 chdir is essentially a wrapper around SetCurrentDirectory; however,
690 it also needs to set "magic" environment variables indicating
691 the per-drive current directory, which are of the form =<drive>: */
692BOOL __stdcall
693win32_chdir(LPCSTR path)
694{
695 char new_path[MAX_PATH+1];
696 int result;
697 char env[4] = "=x:";
698
699 if(!SetCurrentDirectoryA(path))
700 return FALSE;
701 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
702 if (!result)
703 return FALSE;
704 /* In the ANSI API, there should not be any paths longer
705 than MAX_PATH. */
706 assert(result <= MAX_PATH+1);
707 if (strncmp(new_path, "\\\\", 2) == 0 ||
708 strncmp(new_path, "//", 2) == 0)
709 /* UNC path, nothing to do. */
710 return TRUE;
711 env[1] = new_path[0];
712 return SetEnvironmentVariableA(env, new_path);
713}
714
715/* The Unicode version differs from the ANSI version
716 since the current directory might exceed MAX_PATH characters */
717BOOL __stdcall
718win32_wchdir(LPCWSTR path)
719{
720 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
721 int result;
722 wchar_t env[4] = L"=x:";
723
724 if(!SetCurrentDirectoryW(path))
725 return FALSE;
726 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
727 if (!result)
728 return FALSE;
729 if (result > MAX_PATH+1) {
730 new_path = malloc(result);
731 if (!new_path) {
732 SetLastError(ERROR_OUTOFMEMORY);
733 return FALSE;
734 }
735 }
736 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
737 wcsncmp(new_path, L"//", 2) == 0)
738 /* UNC path, nothing to do. */
739 return TRUE;
740 env[1] = new_path[0];
741 result = SetEnvironmentVariableW(env, new_path);
742 if (new_path != _new_path)
743 free(new_path);
744 return result;
745}
746#endif
747
Martin v. Löwis14694662006-02-03 12:54:16 +0000748#ifdef MS_WINDOWS
749/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
750 - time stamps are restricted to second resolution
751 - file modification times suffer from forth-and-back conversions between
752 UTC and local time
753 Therefore, we implement our own stat, based on the Win32 API directly.
754*/
755#define HAVE_STAT_NSEC 1
756
757struct win32_stat{
758 int st_dev;
759 __int64 st_ino;
760 unsigned short st_mode;
761 int st_nlink;
762 int st_uid;
763 int st_gid;
764 int st_rdev;
765 __int64 st_size;
766 int st_atime;
767 int st_atime_nsec;
768 int st_mtime;
769 int st_mtime_nsec;
770 int st_ctime;
771 int st_ctime_nsec;
772};
773
774static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
775
776static void
777FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
778{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000779 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
780 /* Cannot simply cast and dereference in_ptr,
781 since it might not be aligned properly */
782 __int64 in;
783 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000784 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
785 /* XXX Win32 supports time stamps past 2038; we currently don't */
786 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
787}
788
Thomas Wouters477c8d52006-05-27 19:21:47 +0000789static void
790time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
791{
792 /* XXX endianness */
793 __int64 out;
794 out = time_in + secs_between_epochs;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000795 out = out * 10000000 + nsec_in / 100;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000796 memcpy(out_ptr, &out, sizeof(out));
797}
798
Martin v. Löwis14694662006-02-03 12:54:16 +0000799/* Below, we *know* that ugo+r is 0444 */
800#if _S_IREAD != 0400
801#error Unsupported C library
802#endif
803static int
804attributes_to_mode(DWORD attr)
805{
806 int m = 0;
807 if (attr & FILE_ATTRIBUTE_DIRECTORY)
808 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
809 else
810 m |= _S_IFREG;
811 if (attr & FILE_ATTRIBUTE_READONLY)
812 m |= 0444;
813 else
814 m |= 0666;
815 return m;
816}
817
818static int
819attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
820{
821 memset(result, 0, sizeof(*result));
822 result->st_mode = attributes_to_mode(info->dwFileAttributes);
823 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
824 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
825 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
826 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
827
828 return 0;
829}
830
Thomas Wouters89f507f2006-12-13 04:49:30 +0000831/* Emulate GetFileAttributesEx[AW] on Windows 95 */
832static int checked = 0;
833static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
834static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
835static void
836check_gfax()
837{
838 HINSTANCE hKernel32;
839 if (checked)
840 return;
841 checked = 1;
842 hKernel32 = GetModuleHandle("KERNEL32");
843 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
844 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
845}
846
Guido van Rossumd8faa362007-04-27 19:54:29 +0000847static BOOL
848attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
849{
850 HANDLE hFindFile;
851 WIN32_FIND_DATAA FileData;
852 hFindFile = FindFirstFileA(pszFile, &FileData);
853 if (hFindFile == INVALID_HANDLE_VALUE)
854 return FALSE;
855 FindClose(hFindFile);
856 pfad->dwFileAttributes = FileData.dwFileAttributes;
857 pfad->ftCreationTime = FileData.ftCreationTime;
858 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
859 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
860 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
861 pfad->nFileSizeLow = FileData.nFileSizeLow;
862 return TRUE;
863}
864
865static BOOL
866attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
867{
868 HANDLE hFindFile;
869 WIN32_FIND_DATAW FileData;
870 hFindFile = FindFirstFileW(pszFile, &FileData);
871 if (hFindFile == INVALID_HANDLE_VALUE)
872 return FALSE;
873 FindClose(hFindFile);
874 pfad->dwFileAttributes = FileData.dwFileAttributes;
875 pfad->ftCreationTime = FileData.ftCreationTime;
876 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
877 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
878 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
879 pfad->nFileSizeLow = FileData.nFileSizeLow;
880 return TRUE;
881}
882
Thomas Wouters89f507f2006-12-13 04:49:30 +0000883static BOOL WINAPI
884Py_GetFileAttributesExA(LPCSTR pszFile,
885 GET_FILEEX_INFO_LEVELS level,
886 LPVOID pv)
887{
888 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000889 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
890 /* First try to use the system's implementation, if that is
891 available and either succeeds to gives an error other than
892 that it isn't implemented. */
893 check_gfax();
894 if (gfaxa) {
895 result = gfaxa(pszFile, level, pv);
896 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
897 return result;
898 }
899 /* It's either not present, or not implemented.
900 Emulate using FindFirstFile. */
901 if (level != GetFileExInfoStandard) {
902 SetLastError(ERROR_INVALID_PARAMETER);
903 return FALSE;
904 }
905 /* Use GetFileAttributes to validate that the file name
906 does not contain wildcards (which FindFirstFile would
907 accept). */
908 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
909 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000910 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000911}
912
913static BOOL WINAPI
914Py_GetFileAttributesExW(LPCWSTR pszFile,
915 GET_FILEEX_INFO_LEVELS level,
916 LPVOID pv)
917{
918 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000919 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
920 /* First try to use the system's implementation, if that is
921 available and either succeeds to gives an error other than
922 that it isn't implemented. */
923 check_gfax();
924 if (gfaxa) {
925 result = gfaxw(pszFile, level, pv);
926 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
927 return result;
928 }
929 /* It's either not present, or not implemented.
930 Emulate using FindFirstFile. */
931 if (level != GetFileExInfoStandard) {
932 SetLastError(ERROR_INVALID_PARAMETER);
933 return FALSE;
934 }
935 /* Use GetFileAttributes to validate that the file name
936 does not contain wildcards (which FindFirstFile would
937 accept). */
938 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
939 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000940 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000941}
942
Martin v. Löwis14694662006-02-03 12:54:16 +0000943static int
944win32_stat(const char* path, struct win32_stat *result)
945{
946 WIN32_FILE_ATTRIBUTE_DATA info;
947 int code;
948 char *dot;
949 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +0000950 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +0000951 if (GetLastError() != ERROR_SHARING_VIOLATION) {
952 /* Protocol violation: we explicitly clear errno, instead of
953 setting it to a POSIX error. Callers should use GetLastError. */
954 errno = 0;
955 return -1;
956 } else {
957 /* Could not get attributes on open file. Fall back to
958 reading the directory. */
959 if (!attributes_from_dir(path, &info)) {
960 /* Very strange. This should not fail now */
961 errno = 0;
962 return -1;
963 }
964 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000965 }
966 code = attribute_data_to_stat(&info, result);
967 if (code != 0)
968 return code;
969 /* Set S_IFEXEC if it is an .exe, .bat, ... */
970 dot = strrchr(path, '.');
971 if (dot) {
972 if (stricmp(dot, ".bat") == 0 ||
973 stricmp(dot, ".cmd") == 0 ||
974 stricmp(dot, ".exe") == 0 ||
975 stricmp(dot, ".com") == 0)
976 result->st_mode |= 0111;
977 }
978 return code;
979}
980
981static int
982win32_wstat(const wchar_t* path, struct win32_stat *result)
983{
984 int code;
985 const wchar_t *dot;
986 WIN32_FILE_ATTRIBUTE_DATA info;
987 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +0000988 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +0000989 if (GetLastError() != ERROR_SHARING_VIOLATION) {
990 /* Protocol violation: we explicitly clear errno, instead of
991 setting it to a POSIX error. Callers should use GetLastError. */
992 errno = 0;
993 return -1;
994 } else {
995 /* Could not get attributes on open file. Fall back to
996 reading the directory. */
997 if (!attributes_from_dir_w(path, &info)) {
998 /* Very strange. This should not fail now */
999 errno = 0;
1000 return -1;
1001 }
1002 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001003 }
1004 code = attribute_data_to_stat(&info, result);
1005 if (code < 0)
1006 return code;
1007 /* Set IFEXEC if it is an .exe, .bat, ... */
1008 dot = wcsrchr(path, '.');
1009 if (dot) {
1010 if (_wcsicmp(dot, L".bat") == 0 ||
1011 _wcsicmp(dot, L".cmd") == 0 ||
1012 _wcsicmp(dot, L".exe") == 0 ||
1013 _wcsicmp(dot, L".com") == 0)
1014 result->st_mode |= 0111;
1015 }
1016 return code;
1017}
1018
1019static int
1020win32_fstat(int file_number, struct win32_stat *result)
1021{
1022 BY_HANDLE_FILE_INFORMATION info;
1023 HANDLE h;
1024 int type;
1025
1026 h = (HANDLE)_get_osfhandle(file_number);
1027
1028 /* Protocol violation: we explicitly clear errno, instead of
1029 setting it to a POSIX error. Callers should use GetLastError. */
1030 errno = 0;
1031
1032 if (h == INVALID_HANDLE_VALUE) {
1033 /* This is really a C library error (invalid file handle).
1034 We set the Win32 error to the closes one matching. */
1035 SetLastError(ERROR_INVALID_HANDLE);
1036 return -1;
1037 }
1038 memset(result, 0, sizeof(*result));
1039
1040 type = GetFileType(h);
1041 if (type == FILE_TYPE_UNKNOWN) {
1042 DWORD error = GetLastError();
1043 if (error != 0) {
1044 return -1;
1045 }
1046 /* else: valid but unknown file */
1047 }
1048
1049 if (type != FILE_TYPE_DISK) {
1050 if (type == FILE_TYPE_CHAR)
1051 result->st_mode = _S_IFCHR;
1052 else if (type == FILE_TYPE_PIPE)
1053 result->st_mode = _S_IFIFO;
1054 return 0;
1055 }
1056
1057 if (!GetFileInformationByHandle(h, &info)) {
1058 return -1;
1059 }
1060
1061 /* similar to stat() */
1062 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1063 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1064 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1065 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1066 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1067 /* specific to fstat() */
1068 result->st_nlink = info.nNumberOfLinks;
1069 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1070 return 0;
1071}
1072
1073#endif /* MS_WINDOWS */
1074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001075PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001076"stat_result: Result from stat or lstat.\n\n\
1077This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001078 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001079or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1080\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001081Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1082or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001083\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001084See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001085
1086static PyStructSequence_Field stat_result_fields[] = {
1087 {"st_mode", "protection bits"},
1088 {"st_ino", "inode"},
1089 {"st_dev", "device"},
1090 {"st_nlink", "number of hard links"},
1091 {"st_uid", "user ID of owner"},
1092 {"st_gid", "group ID of owner"},
1093 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001094 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1095 {NULL, "integer time of last access"},
1096 {NULL, "integer time of last modification"},
1097 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001098 {"st_atime", "time of last access"},
1099 {"st_mtime", "time of last modification"},
1100 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001101#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001102 {"st_blksize", "blocksize for filesystem I/O"},
1103#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001104#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001105 {"st_blocks", "number of blocks allocated"},
1106#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001107#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001108 {"st_rdev", "device type (if inode device)"},
1109#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001110#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1111 {"st_flags", "user defined flags for file"},
1112#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001113#ifdef HAVE_STRUCT_STAT_ST_GEN
1114 {"st_gen", "generation number"},
1115#endif
1116#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1117 {"st_birthtime", "time of creation"},
1118#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001119 {0}
1120};
1121
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001122#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001123#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001124#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001125#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001126#endif
1127
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001128#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001129#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1130#else
1131#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1132#endif
1133
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001134#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001135#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1136#else
1137#define ST_RDEV_IDX ST_BLOCKS_IDX
1138#endif
1139
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001140#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1141#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1142#else
1143#define ST_FLAGS_IDX ST_RDEV_IDX
1144#endif
1145
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001146#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001147#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001148#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001149#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001150#endif
1151
1152#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1153#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1154#else
1155#define ST_BIRTHTIME_IDX ST_GEN_IDX
1156#endif
1157
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001158static PyStructSequence_Desc stat_result_desc = {
1159 "stat_result", /* name */
1160 stat_result__doc__, /* doc */
1161 stat_result_fields,
1162 10
1163};
1164
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001165PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001166"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1167This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001168 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001169or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001170\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001171See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001172
1173static PyStructSequence_Field statvfs_result_fields[] = {
1174 {"f_bsize", },
1175 {"f_frsize", },
1176 {"f_blocks", },
1177 {"f_bfree", },
1178 {"f_bavail", },
1179 {"f_files", },
1180 {"f_ffree", },
1181 {"f_favail", },
1182 {"f_flag", },
1183 {"f_namemax",},
1184 {0}
1185};
1186
1187static PyStructSequence_Desc statvfs_result_desc = {
1188 "statvfs_result", /* name */
1189 statvfs_result__doc__, /* doc */
1190 statvfs_result_fields,
1191 10
1192};
1193
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001194static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001195static PyTypeObject StatResultType;
1196static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001197static newfunc structseq_new;
1198
1199static PyObject *
1200statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1201{
1202 PyStructSequence *result;
1203 int i;
1204
1205 result = (PyStructSequence*)structseq_new(type, args, kwds);
1206 if (!result)
1207 return NULL;
1208 /* If we have been initialized from a tuple,
1209 st_?time might be set to None. Initialize it
1210 from the int slots. */
1211 for (i = 7; i <= 9; i++) {
1212 if (result->ob_item[i+3] == Py_None) {
1213 Py_DECREF(Py_None);
1214 Py_INCREF(result->ob_item[i]);
1215 result->ob_item[i+3] = result->ob_item[i];
1216 }
1217 }
1218 return (PyObject*)result;
1219}
1220
1221
1222
1223/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001224static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001225
1226PyDoc_STRVAR(stat_float_times__doc__,
1227"stat_float_times([newval]) -> oldval\n\n\
1228Determine whether os.[lf]stat represents time stamps as float objects.\n\
1229If newval is True, future calls to stat() return floats, if it is False,\n\
1230future calls return ints. \n\
1231If newval is omitted, return the current setting.\n");
1232
1233static PyObject*
1234stat_float_times(PyObject* self, PyObject *args)
1235{
1236 int newval = -1;
1237 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1238 return NULL;
1239 if (newval == -1)
1240 /* Return old value */
1241 return PyBool_FromLong(_stat_float_times);
1242 _stat_float_times = newval;
1243 Py_INCREF(Py_None);
1244 return Py_None;
1245}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001246
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001247static void
1248fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1249{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001250 PyObject *fval,*ival;
1251#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001252 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001253#else
1254 ival = PyInt_FromLong((long)sec);
1255#endif
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001256 if (!ival)
1257 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001258 if (_stat_float_times) {
1259 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1260 } else {
1261 fval = ival;
1262 Py_INCREF(fval);
1263 }
1264 PyStructSequence_SET_ITEM(v, index, ival);
1265 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001266}
1267
Tim Peters5aa91602002-01-30 05:46:57 +00001268/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001269 (used by posix_stat() and posix_fstat()) */
1270static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001271_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001272{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001273 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001274 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001275 if (v == NULL)
1276 return NULL;
1277
Martin v. Löwis14694662006-02-03 12:54:16 +00001278 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001279#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001280 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001281 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001282#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001283 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001284#endif
1285#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001286 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001287 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001288#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001289 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001290#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001291 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1292 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1293 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001294#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001295 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001296 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001297#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001298 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001299#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001300
Martin v. Löwis14694662006-02-03 12:54:16 +00001301#if defined(HAVE_STAT_TV_NSEC)
1302 ansec = st->st_atim.tv_nsec;
1303 mnsec = st->st_mtim.tv_nsec;
1304 cnsec = st->st_ctim.tv_nsec;
1305#elif defined(HAVE_STAT_TV_NSEC2)
1306 ansec = st->st_atimespec.tv_nsec;
1307 mnsec = st->st_mtimespec.tv_nsec;
1308 cnsec = st->st_ctimespec.tv_nsec;
1309#elif defined(HAVE_STAT_NSEC)
1310 ansec = st->st_atime_nsec;
1311 mnsec = st->st_mtime_nsec;
1312 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001313#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001314 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001315#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001316 fill_time(v, 7, st->st_atime, ansec);
1317 fill_time(v, 8, st->st_mtime, mnsec);
1318 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001319
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001320#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001321 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001322 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001323#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001324#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001325 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001326 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001327#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001328#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001329 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001330 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001331#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001332#ifdef HAVE_STRUCT_STAT_ST_GEN
1333 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001334 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001335#endif
1336#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1337 {
1338 PyObject *val;
1339 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001340 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001341#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001342 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001343#else
1344 bnsec = 0;
1345#endif
1346 if (_stat_float_times) {
1347 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1348 } else {
1349 val = PyInt_FromLong((long)bsec);
1350 }
1351 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1352 val);
1353 }
1354#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001355#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1356 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001357 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001358#endif
Fred Drake699f3522000-06-29 21:12:41 +00001359
1360 if (PyErr_Occurred()) {
1361 Py_DECREF(v);
1362 return NULL;
1363 }
1364
1365 return v;
1366}
1367
Martin v. Löwisd8948722004-06-02 09:57:56 +00001368#ifdef MS_WINDOWS
1369
1370/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1371 where / can be used in place of \ and the trailing slash is optional.
1372 Both SERVER and SHARE must have at least one character.
1373*/
1374
1375#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1376#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001377#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001378#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001379#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001380
Tim Peters4ad82172004-08-30 17:02:04 +00001381static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001382IsUNCRootA(char *path, int pathlen)
1383{
1384 #define ISSLASH ISSLASHA
1385
1386 int i, share;
1387
1388 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1389 /* minimum UNCRoot is \\x\y */
1390 return FALSE;
1391 for (i = 2; i < pathlen ; i++)
1392 if (ISSLASH(path[i])) break;
1393 if (i == 2 || i == pathlen)
1394 /* do not allow \\\SHARE or \\SERVER */
1395 return FALSE;
1396 share = i+1;
1397 for (i = share; i < pathlen; i++)
1398 if (ISSLASH(path[i])) break;
1399 return (i != share && (i == pathlen || i == pathlen-1));
1400
1401 #undef ISSLASH
1402}
1403
1404#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001405static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001406IsUNCRootW(Py_UNICODE *path, int pathlen)
1407{
1408 #define ISSLASH ISSLASHW
1409
1410 int i, share;
1411
1412 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1413 /* minimum UNCRoot is \\x\y */
1414 return FALSE;
1415 for (i = 2; i < pathlen ; i++)
1416 if (ISSLASH(path[i])) break;
1417 if (i == 2 || i == pathlen)
1418 /* do not allow \\\SHARE or \\SERVER */
1419 return FALSE;
1420 share = i+1;
1421 for (i = share; i < pathlen; i++)
1422 if (ISSLASH(path[i])) break;
1423 return (i != share && (i == pathlen || i == pathlen-1));
1424
1425 #undef ISSLASH
1426}
1427#endif /* Py_WIN_WIDE_FILENAMES */
1428#endif /* MS_WINDOWS */
1429
Barry Warsaw53699e91996-12-10 23:23:01 +00001430static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001431posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001432 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001433#ifdef __VMS
1434 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1435#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001436 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001437#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001438 char *wformat,
1439 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001440{
Fred Drake699f3522000-06-29 21:12:41 +00001441 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001442 char *path = NULL; /* pass this to stat; do not free() it */
1443 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001444 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001445 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001446
1447#ifdef Py_WIN_WIDE_FILENAMES
1448 /* If on wide-character-capable OS see if argument
1449 is Unicode and if so use wide API. */
1450 if (unicode_file_names()) {
1451 PyUnicodeObject *po;
1452 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001453 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1454
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001455 Py_BEGIN_ALLOW_THREADS
1456 /* PyUnicode_AS_UNICODE result OK without
1457 thread lock as it is a simple dereference. */
1458 res = wstatfunc(wpath, &st);
1459 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001460
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001461 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001462 return win32_error_unicode("stat", wpath);
1463 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001464 }
1465 /* Drop the argument parsing error as narrow strings
1466 are also valid. */
1467 PyErr_Clear();
1468 }
1469#endif
1470
Tim Peters5aa91602002-01-30 05:46:57 +00001471 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001472 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001473 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001474 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001475
Barry Warsaw53699e91996-12-10 23:23:01 +00001476 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001477 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001478 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001479
1480 if (res != 0) {
1481#ifdef MS_WINDOWS
1482 result = win32_error("stat", pathfree);
1483#else
1484 result = posix_error_with_filename(pathfree);
1485#endif
1486 }
1487 else
1488 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001489
Tim Peters500bd032001-12-19 19:05:01 +00001490 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001491 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001492}
1493
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001494/* POSIX methods */
1495
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001496PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001497"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001498Use the real uid/gid to test for access to a path. Note that most\n\
1499operations will use the effective uid/gid, therefore this routine can\n\
1500be used in a suid/sgid environment to test if the invoking user has the\n\
1501specified access to the path. The mode argument can be F_OK to test\n\
1502existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001503
1504static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001505posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001506{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001507 char *path;
1508 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001509
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001510#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001511 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001512 if (unicode_file_names()) {
1513 PyUnicodeObject *po;
1514 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1515 Py_BEGIN_ALLOW_THREADS
1516 /* PyUnicode_AS_UNICODE OK without thread lock as
1517 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001518 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001519 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001520 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001521 }
1522 /* Drop the argument parsing error as narrow strings
1523 are also valid. */
1524 PyErr_Clear();
1525 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001526 if (!PyArg_ParseTuple(args, "eti:access",
1527 Py_FileSystemDefaultEncoding, &path, &mode))
1528 return 0;
1529 Py_BEGIN_ALLOW_THREADS
1530 attr = GetFileAttributesA(path);
1531 Py_END_ALLOW_THREADS
1532 PyMem_Free(path);
1533finish:
1534 if (attr == 0xFFFFFFFF)
1535 /* File does not exist, or cannot read attributes */
1536 return PyBool_FromLong(0);
1537 /* Access is possible if either write access wasn't requested, or
1538 the file isn't read-only. */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001539 return PyBool_FromLong(!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001540#else
1541 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001542 if (!PyArg_ParseTuple(args, "eti:access",
1543 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001544 return NULL;
1545 Py_BEGIN_ALLOW_THREADS
1546 res = access(path, mode);
1547 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001548 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001549 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001550#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001551}
1552
Guido van Rossumd371ff11999-01-25 16:12:23 +00001553#ifndef F_OK
1554#define F_OK 0
1555#endif
1556#ifndef R_OK
1557#define R_OK 4
1558#endif
1559#ifndef W_OK
1560#define W_OK 2
1561#endif
1562#ifndef X_OK
1563#define X_OK 1
1564#endif
1565
1566#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001567PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001568"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001569Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001570
1571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001572posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001573{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001574 int id;
1575 char *ret;
1576
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001577 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001578 return NULL;
1579
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001580#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001581 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001582 if (id == 0) {
1583 ret = ttyname();
1584 }
1585 else {
1586 ret = NULL;
1587 }
1588#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001589 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001590#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001591 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001592 return posix_error();
1593 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001594}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001595#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001596
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001597#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001598PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001599"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001600Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001601
1602static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001603posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001604{
1605 char *ret;
1606 char buffer[L_ctermid];
1607
Greg Wardb48bc172000-03-01 21:51:56 +00001608#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001609 ret = ctermid_r(buffer);
1610#else
1611 ret = ctermid(buffer);
1612#endif
1613 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001614 return posix_error();
1615 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001616}
1617#endif
1618
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001619PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001620"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001621Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001622
Barry Warsaw53699e91996-12-10 23:23:01 +00001623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001624posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001625{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001626#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001627 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001628#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001629 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001630#elif defined(__VMS)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001631 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001632#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001633 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001634#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001635}
1636
Fred Drake4d1e64b2002-04-15 19:40:07 +00001637#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001638PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001639"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001640Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001641opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001642
1643static PyObject *
1644posix_fchdir(PyObject *self, PyObject *fdobj)
1645{
1646 return posix_fildes(fdobj, fchdir);
1647}
1648#endif /* HAVE_FCHDIR */
1649
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001650
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001651PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001652"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001653Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001654
Barry Warsaw53699e91996-12-10 23:23:01 +00001655static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001656posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001657{
Mark Hammondef8b6542001-05-13 08:04:26 +00001658 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001659 int i;
1660 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001661#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001662 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001663 if (unicode_file_names()) {
1664 PyUnicodeObject *po;
1665 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1666 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001667 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1668 if (attr != 0xFFFFFFFF) {
1669 if (i & _S_IWRITE)
1670 attr &= ~FILE_ATTRIBUTE_READONLY;
1671 else
1672 attr |= FILE_ATTRIBUTE_READONLY;
1673 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1674 }
1675 else
1676 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001677 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001678 if (!res)
1679 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001680 PyUnicode_AS_UNICODE(po));
1681 Py_INCREF(Py_None);
1682 return Py_None;
1683 }
1684 /* Drop the argument parsing error as narrow strings
1685 are also valid. */
1686 PyErr_Clear();
1687 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001688 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1689 &path, &i))
1690 return NULL;
1691 Py_BEGIN_ALLOW_THREADS
1692 attr = GetFileAttributesA(path);
1693 if (attr != 0xFFFFFFFF) {
1694 if (i & _S_IWRITE)
1695 attr &= ~FILE_ATTRIBUTE_READONLY;
1696 else
1697 attr |= FILE_ATTRIBUTE_READONLY;
1698 res = SetFileAttributesA(path, attr);
1699 }
1700 else
1701 res = 0;
1702 Py_END_ALLOW_THREADS
1703 if (!res) {
1704 win32_error("chmod", path);
1705 PyMem_Free(path);
1706 return NULL;
1707 }
1708 PyMem_Free(path);
1709 Py_INCREF(Py_None);
1710 return Py_None;
1711#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001712 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001713 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001714 return NULL;
1715 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001716 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001717 Py_END_ALLOW_THREADS
1718 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001719 return posix_error_with_allocated_filename(path);
1720 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001721 Py_INCREF(Py_None);
1722 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001723#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001724}
1725
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001726
Thomas Wouterscf297e42007-02-23 15:07:44 +00001727#ifdef HAVE_CHFLAGS
1728PyDoc_STRVAR(posix_chflags__doc__,
1729"chflags(path, flags)\n\n\
1730Set file flags.");
1731
1732static PyObject *
1733posix_chflags(PyObject *self, PyObject *args)
1734{
1735 char *path;
1736 unsigned long flags;
1737 int res;
1738 if (!PyArg_ParseTuple(args, "etk:chflags",
1739 Py_FileSystemDefaultEncoding, &path, &flags))
1740 return NULL;
1741 Py_BEGIN_ALLOW_THREADS
1742 res = chflags(path, flags);
1743 Py_END_ALLOW_THREADS
1744 if (res < 0)
1745 return posix_error_with_allocated_filename(path);
1746 PyMem_Free(path);
1747 Py_INCREF(Py_None);
1748 return Py_None;
1749}
1750#endif /* HAVE_CHFLAGS */
1751
1752#ifdef HAVE_LCHFLAGS
1753PyDoc_STRVAR(posix_lchflags__doc__,
1754"lchflags(path, flags)\n\n\
1755Set file flags.\n\
1756This function will not follow symbolic links.");
1757
1758static PyObject *
1759posix_lchflags(PyObject *self, PyObject *args)
1760{
1761 char *path;
1762 unsigned long flags;
1763 int res;
1764 if (!PyArg_ParseTuple(args, "etk:lchflags",
1765 Py_FileSystemDefaultEncoding, &path, &flags))
1766 return NULL;
1767 Py_BEGIN_ALLOW_THREADS
1768 res = lchflags(path, flags);
1769 Py_END_ALLOW_THREADS
1770 if (res < 0)
1771 return posix_error_with_allocated_filename(path);
1772 PyMem_Free(path);
1773 Py_INCREF(Py_None);
1774 return Py_None;
1775}
1776#endif /* HAVE_LCHFLAGS */
1777
Martin v. Löwis244edc82001-10-04 22:44:26 +00001778#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001779PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001780"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001781Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001782
1783static PyObject *
1784posix_chroot(PyObject *self, PyObject *args)
1785{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001786 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001787}
1788#endif
1789
Guido van Rossum21142a01999-01-08 21:05:37 +00001790#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001791PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001792"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001793force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001794
1795static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001796posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001797{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001798 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001799}
1800#endif /* HAVE_FSYNC */
1801
1802#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001803
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001804#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001805extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1806#endif
1807
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001808PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001809"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001810force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001811 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001812
1813static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001814posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001815{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001816 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001817}
1818#endif /* HAVE_FDATASYNC */
1819
1820
Fredrik Lundh10723342000-07-10 16:38:09 +00001821#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001822PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001823"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001824Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001825
Barry Warsaw53699e91996-12-10 23:23:01 +00001826static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001827posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001828{
Mark Hammondef8b6542001-05-13 08:04:26 +00001829 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001830 int uid, gid;
1831 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001832 if (!PyArg_ParseTuple(args, "etii:chown",
1833 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001834 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001835 return NULL;
1836 Py_BEGIN_ALLOW_THREADS
1837 res = chown(path, (uid_t) uid, (gid_t) gid);
1838 Py_END_ALLOW_THREADS
1839 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001840 return posix_error_with_allocated_filename(path);
1841 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001842 Py_INCREF(Py_None);
1843 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001844}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001845#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001846
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001847#ifdef HAVE_LCHOWN
1848PyDoc_STRVAR(posix_lchown__doc__,
1849"lchown(path, uid, gid)\n\n\
1850Change the owner and group id of path to the numeric uid and gid.\n\
1851This function will not follow symbolic links.");
1852
1853static PyObject *
1854posix_lchown(PyObject *self, PyObject *args)
1855{
1856 char *path = NULL;
1857 int uid, gid;
1858 int res;
1859 if (!PyArg_ParseTuple(args, "etii:lchown",
1860 Py_FileSystemDefaultEncoding, &path,
1861 &uid, &gid))
1862 return NULL;
1863 Py_BEGIN_ALLOW_THREADS
1864 res = lchown(path, (uid_t) uid, (gid_t) gid);
1865 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001866 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001867 return posix_error_with_allocated_filename(path);
1868 PyMem_Free(path);
1869 Py_INCREF(Py_None);
1870 return Py_None;
1871}
1872#endif /* HAVE_LCHOWN */
1873
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001874
Guido van Rossum36bc6801995-06-14 22:54:23 +00001875#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001876PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001877"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001878Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001879
Barry Warsaw53699e91996-12-10 23:23:01 +00001880static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001881posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001882{
1883 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001884 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001885
Barry Warsaw53699e91996-12-10 23:23:01 +00001886 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001887#if defined(PYOS_OS2) && defined(PYCC_GCC)
1888 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001889#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001890 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001891#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001892 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001893 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001894 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001895 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001896}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001897
Walter Dörwald3b918c32002-11-21 20:18:46 +00001898#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001899PyDoc_STRVAR(posix_getcwdu__doc__,
1900"getcwdu() -> path\n\n\
1901Return a unicode string representing the current working directory.");
1902
1903static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001904posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001905{
1906 char buf[1026];
1907 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001908
1909#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001910 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001911 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001912 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001913 wchar_t *wbuf2 = wbuf;
1914 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001915 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001916 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
1917 /* If the buffer is large enough, len does not include the
1918 terminating \0. If the buffer is too small, len includes
1919 the space needed for the terminator. */
1920 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
1921 wbuf2 = malloc(len * sizeof(wchar_t));
1922 if (wbuf2)
1923 len = GetCurrentDirectoryW(len, wbuf2);
1924 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001925 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001926 if (!wbuf2) {
1927 PyErr_NoMemory();
1928 return NULL;
1929 }
1930 if (!len) {
1931 if (wbuf2 != wbuf) free(wbuf2);
1932 return win32_error("getcwdu", NULL);
1933 }
1934 resobj = PyUnicode_FromWideChar(wbuf2, len);
1935 if (wbuf2 != wbuf) free(wbuf2);
1936 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001937 }
1938#endif
1939
1940 Py_BEGIN_ALLOW_THREADS
1941#if defined(PYOS_OS2) && defined(PYCC_GCC)
1942 res = _getcwd2(buf, sizeof buf);
1943#else
1944 res = getcwd(buf, sizeof buf);
1945#endif
1946 Py_END_ALLOW_THREADS
1947 if (res == NULL)
1948 return posix_error();
1949 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1950}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001951#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001952#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001953
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001954
Guido van Rossumb6775db1994-08-01 11:34:53 +00001955#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001956PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001957"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001958Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001959
Barry Warsaw53699e91996-12-10 23:23:01 +00001960static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001961posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001962{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001963 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001964}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001965#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001966
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001967
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001968PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001969"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001970Return a list containing the names of the entries in the directory.\n\
1971\n\
1972 path: path of directory to list\n\
1973\n\
1974The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001975entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001976
Barry Warsaw53699e91996-12-10 23:23:01 +00001977static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001978posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001979{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001980 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001981 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001982#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001983
Barry Warsaw53699e91996-12-10 23:23:01 +00001984 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001985 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001986 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001987 WIN32_FIND_DATA FileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001988 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00001989 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001990 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001991
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001992#ifdef Py_WIN_WIDE_FILENAMES
1993 /* If on wide-character-capable OS see if argument
1994 is Unicode and if so use wide API. */
1995 if (unicode_file_names()) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001996 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001997 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1998 WIN32_FIND_DATAW wFileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001999 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002000 Py_UNICODE wch;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002001 /* Overallocate for \\*.*\0 */
2002 len = PyUnicode_GET_SIZE(po);
2003 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2004 if (!wnamebuf) {
2005 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002006 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002007 }
2008 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2009 wch = len > 0 ? wnamebuf[len-1] : '\0';
2010 if (wch != L'/' && wch != L'\\' && wch != L':')
2011 wnamebuf[len++] = L'\\';
2012 wcscpy(wnamebuf + len, L"*.*");
2013 if ((d = PyList_New(0)) == NULL) {
2014 free(wnamebuf);
2015 return NULL;
2016 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002017 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2018 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002019 int error = GetLastError();
2020 if (error == ERROR_FILE_NOT_FOUND) {
2021 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002022 return d;
2023 }
2024 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002025 win32_error_unicode("FindFirstFileW", wnamebuf);
2026 free(wnamebuf);
2027 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002028 }
2029 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002030 /* Skip over . and .. */
2031 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2032 wcscmp(wFileData.cFileName, L"..") != 0) {
2033 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2034 if (v == NULL) {
2035 Py_DECREF(d);
2036 d = NULL;
2037 break;
2038 }
2039 if (PyList_Append(d, v) != 0) {
2040 Py_DECREF(v);
2041 Py_DECREF(d);
2042 d = NULL;
2043 break;
2044 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002045 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002046 }
Georg Brandl622927b2006-03-07 12:48:03 +00002047 Py_BEGIN_ALLOW_THREADS
2048 result = FindNextFileW(hFindFile, &wFileData);
2049 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002050 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2051 it got to the end of the directory. */
2052 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2053 Py_DECREF(d);
2054 win32_error_unicode("FindNextFileW", wnamebuf);
2055 FindClose(hFindFile);
2056 free(wnamebuf);
2057 return NULL;
2058 }
Georg Brandl622927b2006-03-07 12:48:03 +00002059 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002060
2061 if (FindClose(hFindFile) == FALSE) {
2062 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002063 win32_error_unicode("FindClose", wnamebuf);
2064 free(wnamebuf);
2065 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002066 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002067 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002068 return d;
2069 }
2070 /* Drop the argument parsing error as narrow strings
2071 are also valid. */
2072 PyErr_Clear();
2073 }
2074#endif
2075
Tim Peters5aa91602002-01-30 05:46:57 +00002076 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002077 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002078 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002079 if (len > 0) {
2080 char ch = namebuf[len-1];
2081 if (ch != SEP && ch != ALTSEP && ch != ':')
2082 namebuf[len++] = '/';
2083 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002084 strcpy(namebuf + len, "*.*");
2085
Barry Warsaw53699e91996-12-10 23:23:01 +00002086 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002087 return NULL;
2088
2089 hFindFile = FindFirstFile(namebuf, &FileData);
2090 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002091 int error = GetLastError();
2092 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002093 return d;
2094 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002095 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002096 }
2097 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002098 /* Skip over . and .. */
2099 if (strcmp(FileData.cFileName, ".") != 0 &&
2100 strcmp(FileData.cFileName, "..") != 0) {
2101 v = PyString_FromString(FileData.cFileName);
2102 if (v == NULL) {
2103 Py_DECREF(d);
2104 d = NULL;
2105 break;
2106 }
2107 if (PyList_Append(d, v) != 0) {
2108 Py_DECREF(v);
2109 Py_DECREF(d);
2110 d = NULL;
2111 break;
2112 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002113 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002114 }
Georg Brandl622927b2006-03-07 12:48:03 +00002115 Py_BEGIN_ALLOW_THREADS
2116 result = FindNextFile(hFindFile, &FileData);
2117 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002118 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2119 it got to the end of the directory. */
2120 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2121 Py_DECREF(d);
2122 win32_error("FindNextFile", namebuf);
2123 FindClose(hFindFile);
2124 return NULL;
2125 }
Georg Brandl622927b2006-03-07 12:48:03 +00002126 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002127
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002128 if (FindClose(hFindFile) == FALSE) {
2129 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002130 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002131 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002132
2133 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002134
Tim Peters0bb44a42000-09-15 07:44:49 +00002135#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002136
2137#ifndef MAX_PATH
2138#define MAX_PATH CCHMAXPATH
2139#endif
2140 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002141 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002142 PyObject *d, *v;
2143 char namebuf[MAX_PATH+5];
2144 HDIR hdir = 1;
2145 ULONG srchcnt = 1;
2146 FILEFINDBUF3 ep;
2147 APIRET rc;
2148
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002149 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002150 return NULL;
2151 if (len >= MAX_PATH) {
2152 PyErr_SetString(PyExc_ValueError, "path too long");
2153 return NULL;
2154 }
2155 strcpy(namebuf, name);
2156 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002157 if (*pt == ALTSEP)
2158 *pt = SEP;
2159 if (namebuf[len-1] != SEP)
2160 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002161 strcpy(namebuf + len, "*.*");
2162
2163 if ((d = PyList_New(0)) == NULL)
2164 return NULL;
2165
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002166 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2167 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002168 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002169 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2170 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2171 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002172
2173 if (rc != NO_ERROR) {
2174 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002175 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002176 }
2177
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002178 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002179 do {
2180 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002181 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002182 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002183
2184 strcpy(namebuf, ep.achName);
2185
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002186 /* Leave Case of Name Alone -- In Native Form */
2187 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002188
2189 v = PyString_FromString(namebuf);
2190 if (v == NULL) {
2191 Py_DECREF(d);
2192 d = NULL;
2193 break;
2194 }
2195 if (PyList_Append(d, v) != 0) {
2196 Py_DECREF(v);
2197 Py_DECREF(d);
2198 d = NULL;
2199 break;
2200 }
2201 Py_DECREF(v);
2202 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2203 }
2204
2205 return d;
2206#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002207
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002208 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002209 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002210 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002211 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002212 int arg_is_unicode = 1;
2213
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002214 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002215 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2216 arg_is_unicode = 0;
2217 PyErr_Clear();
2218 }
2219 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002220 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002221 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002222 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002223 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002224 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002225 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002226 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002227 return NULL;
2228 }
Georg Brandl622927b2006-03-07 12:48:03 +00002229 for (;;) {
2230 Py_BEGIN_ALLOW_THREADS
2231 ep = readdir(dirp);
2232 Py_END_ALLOW_THREADS
2233 if (ep == NULL)
2234 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002235 if (ep->d_name[0] == '.' &&
2236 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002237 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002238 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00002239 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002240 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002241 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002242 d = NULL;
2243 break;
2244 }
Just van Rossum46c97842003-02-25 21:42:15 +00002245#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002246 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002247 PyObject *w;
2248
2249 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002250 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002251 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002252 if (w != NULL) {
2253 Py_DECREF(v);
2254 v = w;
2255 }
2256 else {
2257 /* fall back to the original byte string, as
2258 discussed in patch #683592 */
2259 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002260 }
Just van Rossum46c97842003-02-25 21:42:15 +00002261 }
2262#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002263 if (PyList_Append(d, v) != 0) {
2264 Py_DECREF(v);
2265 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002266 d = NULL;
2267 break;
2268 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002269 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002270 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002271 if (errno != 0 && d != NULL) {
2272 /* readdir() returned NULL and set errno */
2273 closedir(dirp);
2274 Py_DECREF(d);
2275 return posix_error_with_allocated_filename(name);
2276 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002277 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002278 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002279
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002280 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002281
Tim Peters0bb44a42000-09-15 07:44:49 +00002282#endif /* which OS */
2283} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002284
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002285#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002286/* A helper function for abspath on win32 */
2287static PyObject *
2288posix__getfullpathname(PyObject *self, PyObject *args)
2289{
2290 /* assume encoded strings wont more than double no of chars */
2291 char inbuf[MAX_PATH*2];
2292 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002293 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002294 char outbuf[MAX_PATH*2];
2295 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002296#ifdef Py_WIN_WIDE_FILENAMES
2297 if (unicode_file_names()) {
2298 PyUnicodeObject *po;
2299 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2300 Py_UNICODE woutbuf[MAX_PATH*2];
2301 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002302 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002303 sizeof(woutbuf)/sizeof(woutbuf[0]),
2304 woutbuf, &wtemp))
2305 return win32_error("GetFullPathName", "");
2306 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2307 }
2308 /* Drop the argument parsing error as narrow strings
2309 are also valid. */
2310 PyErr_Clear();
2311 }
2312#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002313 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2314 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002315 &insize))
2316 return NULL;
2317 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2318 outbuf, &temp))
2319 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002320 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2321 return PyUnicode_Decode(outbuf, strlen(outbuf),
2322 Py_FileSystemDefaultEncoding, NULL);
2323 }
Mark Hammondef8b6542001-05-13 08:04:26 +00002324 return PyString_FromString(outbuf);
2325} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002326#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002327
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002328PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002329"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002330Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002331
Barry Warsaw53699e91996-12-10 23:23:01 +00002332static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002333posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002334{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002335 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002336 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002337 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002338
2339#ifdef Py_WIN_WIDE_FILENAMES
2340 if (unicode_file_names()) {
2341 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002342 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002343 Py_BEGIN_ALLOW_THREADS
2344 /* PyUnicode_AS_UNICODE OK without thread lock as
2345 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002346 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002347 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002348 if (!res)
2349 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002350 Py_INCREF(Py_None);
2351 return Py_None;
2352 }
2353 /* Drop the argument parsing error as narrow strings
2354 are also valid. */
2355 PyErr_Clear();
2356 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002357 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2358 Py_FileSystemDefaultEncoding, &path, &mode))
2359 return NULL;
2360 Py_BEGIN_ALLOW_THREADS
2361 /* PyUnicode_AS_UNICODE OK without thread lock as
2362 it is a simple dereference. */
2363 res = CreateDirectoryA(path, NULL);
2364 Py_END_ALLOW_THREADS
2365 if (!res) {
2366 win32_error("mkdir", path);
2367 PyMem_Free(path);
2368 return NULL;
2369 }
2370 PyMem_Free(path);
2371 Py_INCREF(Py_None);
2372 return Py_None;
2373#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002374
Tim Peters5aa91602002-01-30 05:46:57 +00002375 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002376 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002377 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002378 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002379#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002380 res = mkdir(path);
2381#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002382 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002383#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002384 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002385 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002386 return posix_error_with_allocated_filename(path);
2387 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002388 Py_INCREF(Py_None);
2389 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002390#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002391}
2392
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002393
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002394/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2395#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002396#include <sys/resource.h>
2397#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002398
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002399
2400#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002401PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002402"nice(inc) -> new_priority\n\n\
2403Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002404
Barry Warsaw53699e91996-12-10 23:23:01 +00002405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002406posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002407{
2408 int increment, value;
2409
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002410 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002411 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002412
2413 /* There are two flavours of 'nice': one that returns the new
2414 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002415 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2416 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002417
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002418 If we are of the nice family that returns the new priority, we
2419 need to clear errno before the call, and check if errno is filled
2420 before calling posix_error() on a returnvalue of -1, because the
2421 -1 may be the actual new priority! */
2422
2423 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002424 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002425#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002426 if (value == 0)
2427 value = getpriority(PRIO_PROCESS, 0);
2428#endif
2429 if (value == -1 && errno != 0)
2430 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002431 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002432 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002433}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002434#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002435
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002436PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002437"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002438Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002439
Barry Warsaw53699e91996-12-10 23:23:01 +00002440static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002441posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002442{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002443#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002444 PyObject *o1, *o2;
2445 char *p1, *p2;
2446 BOOL result;
2447 if (unicode_file_names()) {
2448 if (!PyArg_ParseTuple(args, "O&O&:rename",
2449 convert_to_unicode, &o1,
2450 convert_to_unicode, &o2))
2451 PyErr_Clear();
2452 else {
2453 Py_BEGIN_ALLOW_THREADS
2454 result = MoveFileW(PyUnicode_AsUnicode(o1),
2455 PyUnicode_AsUnicode(o2));
2456 Py_END_ALLOW_THREADS
2457 Py_DECREF(o1);
2458 Py_DECREF(o2);
2459 if (!result)
2460 return win32_error("rename", NULL);
2461 Py_INCREF(Py_None);
2462 return Py_None;
2463 }
2464 }
2465 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2466 return NULL;
2467 Py_BEGIN_ALLOW_THREADS
2468 result = MoveFileA(p1, p2);
2469 Py_END_ALLOW_THREADS
2470 if (!result)
2471 return win32_error("rename", NULL);
2472 Py_INCREF(Py_None);
2473 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002474#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002475 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002476#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002477}
2478
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002479
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002480PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002481"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002482Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002483
Barry Warsaw53699e91996-12-10 23:23:01 +00002484static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002485posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002486{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002487#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002488 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002489#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002490 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002491#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002492}
2493
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002494
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002495PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002496"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002497Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002498
Barry Warsaw53699e91996-12-10 23:23:01 +00002499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002500posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002501{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002502#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002503 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002504#else
2505 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2506#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002507}
2508
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002509
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002510#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002511PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002512"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002513Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002514
Barry Warsaw53699e91996-12-10 23:23:01 +00002515static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002516posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002517{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002518 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002519 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002520 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002521 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002522 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002523 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002524 Py_END_ALLOW_THREADS
2525 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002526}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002527#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002528
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002529
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002530PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002531"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002532Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002533
Barry Warsaw53699e91996-12-10 23:23:01 +00002534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002535posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002536{
2537 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002538 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002539 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002540 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002541 if (i < 0)
2542 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002543 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002544}
2545
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002546
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002547PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002548"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002549Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002550
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002551PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002552"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002553Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002554
Barry Warsaw53699e91996-12-10 23:23:01 +00002555static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002556posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002557{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002558#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002559 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002560#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002561 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002562#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002563}
2564
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002565
Guido van Rossumb6775db1994-08-01 11:34:53 +00002566#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002567PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002568"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002569Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002570
Barry Warsaw53699e91996-12-10 23:23:01 +00002571static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002572posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002573{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002574 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002575 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002576
Barry Warsaw53699e91996-12-10 23:23:01 +00002577 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002578 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002579 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002580 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002581 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002582 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002583 u.sysname,
2584 u.nodename,
2585 u.release,
2586 u.version,
2587 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002588}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002589#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002590
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002591static int
2592extract_time(PyObject *t, long* sec, long* usec)
2593{
2594 long intval;
2595 if (PyFloat_Check(t)) {
2596 double tval = PyFloat_AsDouble(t);
2597 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2598 if (!intobj)
2599 return -1;
2600 intval = PyInt_AsLong(intobj);
2601 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002602 if (intval == -1 && PyErr_Occurred())
2603 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002604 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002605 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002606 if (*usec < 0)
2607 /* If rounding gave us a negative number,
2608 truncate. */
2609 *usec = 0;
2610 return 0;
2611 }
2612 intval = PyInt_AsLong(t);
2613 if (intval == -1 && PyErr_Occurred())
2614 return -1;
2615 *sec = intval;
2616 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002617 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002618}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002619
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002620PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002621"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002622utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002623Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002624second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002625
Barry Warsaw53699e91996-12-10 23:23:01 +00002626static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002627posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002628{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002629#ifdef Py_WIN_WIDE_FILENAMES
2630 PyObject *arg;
2631 PyUnicodeObject *obwpath;
2632 wchar_t *wpath = NULL;
2633 char *apath = NULL;
2634 HANDLE hFile;
2635 long atimesec, mtimesec, ausec, musec;
2636 FILETIME atime, mtime;
2637 PyObject *result = NULL;
2638
2639 if (unicode_file_names()) {
2640 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2641 wpath = PyUnicode_AS_UNICODE(obwpath);
2642 Py_BEGIN_ALLOW_THREADS
2643 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002644 NULL, OPEN_EXISTING,
2645 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002646 Py_END_ALLOW_THREADS
2647 if (hFile == INVALID_HANDLE_VALUE)
2648 return win32_error_unicode("utime", wpath);
2649 } else
2650 /* Drop the argument parsing error as narrow strings
2651 are also valid. */
2652 PyErr_Clear();
2653 }
2654 if (!wpath) {
2655 if (!PyArg_ParseTuple(args, "etO:utime",
2656 Py_FileSystemDefaultEncoding, &apath, &arg))
2657 return NULL;
2658 Py_BEGIN_ALLOW_THREADS
2659 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002660 NULL, OPEN_EXISTING,
2661 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002662 Py_END_ALLOW_THREADS
2663 if (hFile == INVALID_HANDLE_VALUE) {
2664 win32_error("utime", apath);
2665 PyMem_Free(apath);
2666 return NULL;
2667 }
2668 PyMem_Free(apath);
2669 }
2670
2671 if (arg == Py_None) {
2672 SYSTEMTIME now;
2673 GetSystemTime(&now);
2674 if (!SystemTimeToFileTime(&now, &mtime) ||
2675 !SystemTimeToFileTime(&now, &atime)) {
2676 win32_error("utime", NULL);
2677 goto done;
2678 }
2679 }
2680 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2681 PyErr_SetString(PyExc_TypeError,
2682 "utime() arg 2 must be a tuple (atime, mtime)");
2683 goto done;
2684 }
2685 else {
2686 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2687 &atimesec, &ausec) == -1)
2688 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002689 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002690 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2691 &mtimesec, &musec) == -1)
2692 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002693 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002694 }
2695 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2696 /* Avoid putting the file name into the error here,
2697 as that may confuse the user into believing that
2698 something is wrong with the file, when it also
2699 could be the time stamp that gives a problem. */
2700 win32_error("utime", NULL);
2701 }
2702 Py_INCREF(Py_None);
2703 result = Py_None;
2704done:
2705 CloseHandle(hFile);
2706 return result;
2707#else /* Py_WIN_WIDE_FILENAMES */
2708
Neal Norwitz2adf2102004-06-09 01:46:02 +00002709 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002710 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002711 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002712 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002713
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002714#if defined(HAVE_UTIMES)
2715 struct timeval buf[2];
2716#define ATIME buf[0].tv_sec
2717#define MTIME buf[1].tv_sec
2718#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002719/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002720 struct utimbuf buf;
2721#define ATIME buf.actime
2722#define MTIME buf.modtime
2723#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002724#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002725 time_t buf[2];
2726#define ATIME buf[0]
2727#define MTIME buf[1]
2728#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002729#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002730
Mark Hammond817c9292003-12-03 01:22:38 +00002731
Thomas Wouters477c8d52006-05-27 19:21:47 +00002732 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002733 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002734 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002735 if (arg == Py_None) {
2736 /* optional time values not given */
2737 Py_BEGIN_ALLOW_THREADS
2738 res = utime(path, NULL);
2739 Py_END_ALLOW_THREADS
2740 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002741 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002742 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002743 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002744 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002745 return NULL;
2746 }
2747 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002748 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002749 &atime, &ausec) == -1) {
2750 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002751 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002752 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002753 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002754 &mtime, &musec) == -1) {
2755 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002756 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002757 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002758 ATIME = atime;
2759 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002760#ifdef HAVE_UTIMES
2761 buf[0].tv_usec = ausec;
2762 buf[1].tv_usec = musec;
2763 Py_BEGIN_ALLOW_THREADS
2764 res = utimes(path, buf);
2765 Py_END_ALLOW_THREADS
2766#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002767 Py_BEGIN_ALLOW_THREADS
2768 res = utime(path, UTIME_ARG);
2769 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002770#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002771 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002772 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002773 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002774 }
Neal Norwitz96652712004-06-06 20:40:27 +00002775 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002776 Py_INCREF(Py_None);
2777 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002778#undef UTIME_ARG
2779#undef ATIME
2780#undef MTIME
Thomas Wouters477c8d52006-05-27 19:21:47 +00002781#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002782}
2783
Guido van Rossum85e3b011991-06-03 12:42:10 +00002784
Guido van Rossum3b066191991-06-04 19:40:25 +00002785/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002786
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002787PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002788"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002789Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002790
Barry Warsaw53699e91996-12-10 23:23:01 +00002791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002792posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002793{
2794 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002795 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002796 return NULL;
2797 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002798 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002799}
2800
Martin v. Löwis114619e2002-10-07 06:44:21 +00002801#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2802static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002803free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002804{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002805 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002806 for (i = 0; i < count; i++)
2807 PyMem_Free(array[i]);
2808 PyMem_DEL(array);
2809}
2810#endif
2811
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002812
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002813#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002814PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002815"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002816Execute an executable path with arguments, replacing current process.\n\
2817\n\
2818 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002819 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002820
Barry Warsaw53699e91996-12-10 23:23:01 +00002821static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002822posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002823{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002824 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002825 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002826 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002827 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002828 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002829
Guido van Rossum89b33251993-10-22 14:26:06 +00002830 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002831 argv is a list or tuple of strings. */
2832
Martin v. Löwis114619e2002-10-07 06:44:21 +00002833 if (!PyArg_ParseTuple(args, "etO:execv",
2834 Py_FileSystemDefaultEncoding,
2835 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002836 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002837 if (PyList_Check(argv)) {
2838 argc = PyList_Size(argv);
2839 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002840 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002841 else if (PyTuple_Check(argv)) {
2842 argc = PyTuple_Size(argv);
2843 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002844 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002845 else {
Fred Drake661ea262000-10-24 19:57:45 +00002846 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002847 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002848 return NULL;
2849 }
2850
Barry Warsaw53699e91996-12-10 23:23:01 +00002851 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002852 if (argvlist == NULL) {
2853 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002854 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002855 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002856 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002857 if (!PyArg_Parse((*getitem)(argv, i), "et",
2858 Py_FileSystemDefaultEncoding,
2859 &argvlist[i])) {
2860 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002861 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002862 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002863 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002864 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002865
Guido van Rossum85e3b011991-06-03 12:42:10 +00002866 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002867 }
2868 argvlist[argc] = NULL;
2869
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002870 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002871
Guido van Rossum85e3b011991-06-03 12:42:10 +00002872 /* If we get here it's definitely an error */
2873
Martin v. Löwis114619e2002-10-07 06:44:21 +00002874 free_string_array(argvlist, argc);
2875 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002876 return posix_error();
2877}
2878
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002879
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002880PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002881"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002882Execute a path with arguments and environment, replacing current process.\n\
2883\n\
2884 path: path of executable file\n\
2885 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002886 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002887
Barry Warsaw53699e91996-12-10 23:23:01 +00002888static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002889posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002890{
2891 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002892 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002893 char **argvlist;
2894 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002895 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002896 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002897 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002898 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002899
2900 /* execve has three arguments: (path, argv, env), where
2901 argv is a list or tuple of strings and env is a dictionary
2902 like posix.environ. */
2903
Martin v. Löwis114619e2002-10-07 06:44:21 +00002904 if (!PyArg_ParseTuple(args, "etOO:execve",
2905 Py_FileSystemDefaultEncoding,
2906 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002907 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002908 if (PyList_Check(argv)) {
2909 argc = PyList_Size(argv);
2910 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002911 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002912 else if (PyTuple_Check(argv)) {
2913 argc = PyTuple_Size(argv);
2914 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002915 }
2916 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002917 PyErr_SetString(PyExc_TypeError,
2918 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002919 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002920 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002921 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002922 PyErr_SetString(PyExc_TypeError,
2923 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002924 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002925 }
2926
Barry Warsaw53699e91996-12-10 23:23:01 +00002927 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002928 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002929 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002930 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002931 }
2932 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002933 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002934 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002935 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002936 &argvlist[i]))
2937 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002938 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002939 goto fail_1;
2940 }
2941 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002942 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002943 argvlist[argc] = NULL;
2944
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002945 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002946 if (i < 0)
2947 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002948 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002949 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002950 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002951 goto fail_1;
2952 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002953 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002954 keys = PyMapping_Keys(env);
2955 vals = PyMapping_Values(env);
2956 if (!keys || !vals)
2957 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002958 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2959 PyErr_SetString(PyExc_TypeError,
2960 "execve(): env.keys() or env.values() is not a list");
2961 goto fail_2;
2962 }
Tim Peters5aa91602002-01-30 05:46:57 +00002963
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002964 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002965 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002966 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002967
2968 key = PyList_GetItem(keys, pos);
2969 val = PyList_GetItem(vals, pos);
2970 if (!key || !val)
2971 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002972
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002973 if (!PyArg_Parse(
2974 key,
2975 "s;execve() arg 3 contains a non-string key",
2976 &k) ||
2977 !PyArg_Parse(
2978 val,
2979 "s;execve() arg 3 contains a non-string value",
2980 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002981 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002982 goto fail_2;
2983 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002984
2985#if defined(PYOS_OS2)
2986 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2987 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2988#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002989 len = PyString_Size(key) + PyString_Size(val) + 2;
2990 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002991 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002992 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002993 goto fail_2;
2994 }
Tim Petersc8996f52001-12-03 20:41:00 +00002995 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002996 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002997#if defined(PYOS_OS2)
2998 }
2999#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003000 }
3001 envlist[envc] = 0;
3002
3003 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003004
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003005 /* If we get here it's definitely an error */
3006
3007 (void) posix_error();
3008
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003009 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003010 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003011 PyMem_DEL(envlist[envc]);
3012 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003013 fail_1:
3014 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003015 Py_XDECREF(vals);
3016 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003017 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003018 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003019 return NULL;
3020}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003021#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003022
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003023
Guido van Rossuma1065681999-01-25 23:20:23 +00003024#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003025PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003026"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003027Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003028\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003029 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003030 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003031 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003032
3033static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003034posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003035{
3036 char *path;
3037 PyObject *argv;
3038 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003039 int mode, i;
3040 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003041 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003042 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003043
3044 /* spawnv has three arguments: (mode, path, argv), where
3045 argv is a list or tuple of strings. */
3046
Martin v. Löwis114619e2002-10-07 06:44:21 +00003047 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3048 Py_FileSystemDefaultEncoding,
3049 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003050 return NULL;
3051 if (PyList_Check(argv)) {
3052 argc = PyList_Size(argv);
3053 getitem = PyList_GetItem;
3054 }
3055 else if (PyTuple_Check(argv)) {
3056 argc = PyTuple_Size(argv);
3057 getitem = PyTuple_GetItem;
3058 }
3059 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003060 PyErr_SetString(PyExc_TypeError,
3061 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003062 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003063 return NULL;
3064 }
3065
3066 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003067 if (argvlist == NULL) {
3068 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003069 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003070 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003071 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003072 if (!PyArg_Parse((*getitem)(argv, i), "et",
3073 Py_FileSystemDefaultEncoding,
3074 &argvlist[i])) {
3075 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003076 PyErr_SetString(
3077 PyExc_TypeError,
3078 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003079 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003080 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003081 }
3082 }
3083 argvlist[argc] = NULL;
3084
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003085#if defined(PYOS_OS2) && defined(PYCC_GCC)
3086 Py_BEGIN_ALLOW_THREADS
3087 spawnval = spawnv(mode, path, argvlist);
3088 Py_END_ALLOW_THREADS
3089#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003090 if (mode == _OLD_P_OVERLAY)
3091 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003092
Tim Peters25059d32001-12-07 20:35:43 +00003093 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003094 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003095 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003096#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003097
Martin v. Löwis114619e2002-10-07 06:44:21 +00003098 free_string_array(argvlist, argc);
3099 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003100
Fred Drake699f3522000-06-29 21:12:41 +00003101 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003102 return posix_error();
3103 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003104#if SIZEOF_LONG == SIZEOF_VOID_P
3105 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003106#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003107 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003108#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003109}
3110
3111
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003112PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003113"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003114Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003115\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003116 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003117 path: path of executable file\n\
3118 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003119 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003120
3121static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003122posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003123{
3124 char *path;
3125 PyObject *argv, *env;
3126 char **argvlist;
3127 char **envlist;
3128 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003129 int mode, pos, envc;
3130 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003131 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003132 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003133 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003134
3135 /* spawnve has four arguments: (mode, path, argv, env), where
3136 argv is a list or tuple of strings and env is a dictionary
3137 like posix.environ. */
3138
Martin v. Löwis114619e2002-10-07 06:44:21 +00003139 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3140 Py_FileSystemDefaultEncoding,
3141 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003142 return NULL;
3143 if (PyList_Check(argv)) {
3144 argc = PyList_Size(argv);
3145 getitem = PyList_GetItem;
3146 }
3147 else if (PyTuple_Check(argv)) {
3148 argc = PyTuple_Size(argv);
3149 getitem = PyTuple_GetItem;
3150 }
3151 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003152 PyErr_SetString(PyExc_TypeError,
3153 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003154 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003155 }
3156 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003157 PyErr_SetString(PyExc_TypeError,
3158 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003159 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003160 }
3161
3162 argvlist = PyMem_NEW(char *, argc+1);
3163 if (argvlist == NULL) {
3164 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003165 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003166 }
3167 for (i = 0; i < argc; i++) {
3168 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003169 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003170 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003171 &argvlist[i]))
3172 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003173 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003174 goto fail_1;
3175 }
3176 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003177 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003178 argvlist[argc] = NULL;
3179
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003180 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003181 if (i < 0)
3182 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003183 envlist = PyMem_NEW(char *, i + 1);
3184 if (envlist == NULL) {
3185 PyErr_NoMemory();
3186 goto fail_1;
3187 }
3188 envc = 0;
3189 keys = PyMapping_Keys(env);
3190 vals = PyMapping_Values(env);
3191 if (!keys || !vals)
3192 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003193 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3194 PyErr_SetString(PyExc_TypeError,
3195 "spawnve(): env.keys() or env.values() is not a list");
3196 goto fail_2;
3197 }
Tim Peters5aa91602002-01-30 05:46:57 +00003198
Guido van Rossuma1065681999-01-25 23:20:23 +00003199 for (pos = 0; pos < i; pos++) {
3200 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003201 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003202
3203 key = PyList_GetItem(keys, pos);
3204 val = PyList_GetItem(vals, pos);
3205 if (!key || !val)
3206 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003207
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003208 if (!PyArg_Parse(
3209 key,
3210 "s;spawnve() arg 3 contains a non-string key",
3211 &k) ||
3212 !PyArg_Parse(
3213 val,
3214 "s;spawnve() arg 3 contains a non-string value",
3215 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003216 {
3217 goto fail_2;
3218 }
Tim Petersc8996f52001-12-03 20:41:00 +00003219 len = PyString_Size(key) + PyString_Size(val) + 2;
3220 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003221 if (p == NULL) {
3222 PyErr_NoMemory();
3223 goto fail_2;
3224 }
Tim Petersc8996f52001-12-03 20:41:00 +00003225 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003226 envlist[envc++] = p;
3227 }
3228 envlist[envc] = 0;
3229
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003230#if defined(PYOS_OS2) && defined(PYCC_GCC)
3231 Py_BEGIN_ALLOW_THREADS
3232 spawnval = spawnve(mode, path, argvlist, envlist);
3233 Py_END_ALLOW_THREADS
3234#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003235 if (mode == _OLD_P_OVERLAY)
3236 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003237
3238 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003239 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003240 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003241#endif
Tim Peters25059d32001-12-07 20:35:43 +00003242
Fred Drake699f3522000-06-29 21:12:41 +00003243 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003244 (void) posix_error();
3245 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003246#if SIZEOF_LONG == SIZEOF_VOID_P
3247 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003248#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003249 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003250#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003251
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003252 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003253 while (--envc >= 0)
3254 PyMem_DEL(envlist[envc]);
3255 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003256 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003257 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003258 Py_XDECREF(vals);
3259 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003260 fail_0:
3261 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003262 return res;
3263}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003264
3265/* OS/2 supports spawnvp & spawnvpe natively */
3266#if defined(PYOS_OS2)
3267PyDoc_STRVAR(posix_spawnvp__doc__,
3268"spawnvp(mode, file, args)\n\n\
3269Execute the program 'file' in a new process, using the environment\n\
3270search path to find the file.\n\
3271\n\
3272 mode: mode of process creation\n\
3273 file: executable file name\n\
3274 args: tuple or list of strings");
3275
3276static PyObject *
3277posix_spawnvp(PyObject *self, PyObject *args)
3278{
3279 char *path;
3280 PyObject *argv;
3281 char **argvlist;
3282 int mode, i, argc;
3283 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003284 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003285
3286 /* spawnvp has three arguments: (mode, path, argv), where
3287 argv is a list or tuple of strings. */
3288
3289 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3290 Py_FileSystemDefaultEncoding,
3291 &path, &argv))
3292 return NULL;
3293 if (PyList_Check(argv)) {
3294 argc = PyList_Size(argv);
3295 getitem = PyList_GetItem;
3296 }
3297 else if (PyTuple_Check(argv)) {
3298 argc = PyTuple_Size(argv);
3299 getitem = PyTuple_GetItem;
3300 }
3301 else {
3302 PyErr_SetString(PyExc_TypeError,
3303 "spawnvp() arg 2 must be a tuple or list");
3304 PyMem_Free(path);
3305 return NULL;
3306 }
3307
3308 argvlist = PyMem_NEW(char *, argc+1);
3309 if (argvlist == NULL) {
3310 PyMem_Free(path);
3311 return PyErr_NoMemory();
3312 }
3313 for (i = 0; i < argc; i++) {
3314 if (!PyArg_Parse((*getitem)(argv, i), "et",
3315 Py_FileSystemDefaultEncoding,
3316 &argvlist[i])) {
3317 free_string_array(argvlist, i);
3318 PyErr_SetString(
3319 PyExc_TypeError,
3320 "spawnvp() arg 2 must contain only strings");
3321 PyMem_Free(path);
3322 return NULL;
3323 }
3324 }
3325 argvlist[argc] = NULL;
3326
3327 Py_BEGIN_ALLOW_THREADS
3328#if defined(PYCC_GCC)
3329 spawnval = spawnvp(mode, path, argvlist);
3330#else
3331 spawnval = _spawnvp(mode, path, argvlist);
3332#endif
3333 Py_END_ALLOW_THREADS
3334
3335 free_string_array(argvlist, argc);
3336 PyMem_Free(path);
3337
3338 if (spawnval == -1)
3339 return posix_error();
3340 else
3341 return Py_BuildValue("l", (long) spawnval);
3342}
3343
3344
3345PyDoc_STRVAR(posix_spawnvpe__doc__,
3346"spawnvpe(mode, file, args, env)\n\n\
3347Execute the program 'file' in a new process, using the environment\n\
3348search path to find the file.\n\
3349\n\
3350 mode: mode of process creation\n\
3351 file: executable file name\n\
3352 args: tuple or list of arguments\n\
3353 env: dictionary of strings mapping to strings");
3354
3355static PyObject *
3356posix_spawnvpe(PyObject *self, PyObject *args)
3357{
3358 char *path;
3359 PyObject *argv, *env;
3360 char **argvlist;
3361 char **envlist;
3362 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3363 int mode, i, pos, argc, envc;
3364 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003365 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003366 int lastarg = 0;
3367
3368 /* spawnvpe has four arguments: (mode, path, argv, env), where
3369 argv is a list or tuple of strings and env is a dictionary
3370 like posix.environ. */
3371
3372 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3373 Py_FileSystemDefaultEncoding,
3374 &path, &argv, &env))
3375 return NULL;
3376 if (PyList_Check(argv)) {
3377 argc = PyList_Size(argv);
3378 getitem = PyList_GetItem;
3379 }
3380 else if (PyTuple_Check(argv)) {
3381 argc = PyTuple_Size(argv);
3382 getitem = PyTuple_GetItem;
3383 }
3384 else {
3385 PyErr_SetString(PyExc_TypeError,
3386 "spawnvpe() arg 2 must be a tuple or list");
3387 goto fail_0;
3388 }
3389 if (!PyMapping_Check(env)) {
3390 PyErr_SetString(PyExc_TypeError,
3391 "spawnvpe() arg 3 must be a mapping object");
3392 goto fail_0;
3393 }
3394
3395 argvlist = PyMem_NEW(char *, argc+1);
3396 if (argvlist == NULL) {
3397 PyErr_NoMemory();
3398 goto fail_0;
3399 }
3400 for (i = 0; i < argc; i++) {
3401 if (!PyArg_Parse((*getitem)(argv, i),
3402 "et;spawnvpe() arg 2 must contain only strings",
3403 Py_FileSystemDefaultEncoding,
3404 &argvlist[i]))
3405 {
3406 lastarg = i;
3407 goto fail_1;
3408 }
3409 }
3410 lastarg = argc;
3411 argvlist[argc] = NULL;
3412
3413 i = PyMapping_Size(env);
3414 if (i < 0)
3415 goto fail_1;
3416 envlist = PyMem_NEW(char *, i + 1);
3417 if (envlist == NULL) {
3418 PyErr_NoMemory();
3419 goto fail_1;
3420 }
3421 envc = 0;
3422 keys = PyMapping_Keys(env);
3423 vals = PyMapping_Values(env);
3424 if (!keys || !vals)
3425 goto fail_2;
3426 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3427 PyErr_SetString(PyExc_TypeError,
3428 "spawnvpe(): env.keys() or env.values() is not a list");
3429 goto fail_2;
3430 }
3431
3432 for (pos = 0; pos < i; pos++) {
3433 char *p, *k, *v;
3434 size_t len;
3435
3436 key = PyList_GetItem(keys, pos);
3437 val = PyList_GetItem(vals, pos);
3438 if (!key || !val)
3439 goto fail_2;
3440
3441 if (!PyArg_Parse(
3442 key,
3443 "s;spawnvpe() arg 3 contains a non-string key",
3444 &k) ||
3445 !PyArg_Parse(
3446 val,
3447 "s;spawnvpe() arg 3 contains a non-string value",
3448 &v))
3449 {
3450 goto fail_2;
3451 }
3452 len = PyString_Size(key) + PyString_Size(val) + 2;
3453 p = PyMem_NEW(char, len);
3454 if (p == NULL) {
3455 PyErr_NoMemory();
3456 goto fail_2;
3457 }
3458 PyOS_snprintf(p, len, "%s=%s", k, v);
3459 envlist[envc++] = p;
3460 }
3461 envlist[envc] = 0;
3462
3463 Py_BEGIN_ALLOW_THREADS
3464#if defined(PYCC_GCC)
3465 spawnval = spawnve(mode, path, argvlist, envlist);
3466#else
3467 spawnval = _spawnve(mode, path, argvlist, envlist);
3468#endif
3469 Py_END_ALLOW_THREADS
3470
3471 if (spawnval == -1)
3472 (void) posix_error();
3473 else
3474 res = Py_BuildValue("l", (long) spawnval);
3475
3476 fail_2:
3477 while (--envc >= 0)
3478 PyMem_DEL(envlist[envc]);
3479 PyMem_DEL(envlist);
3480 fail_1:
3481 free_string_array(argvlist, lastarg);
3482 Py_XDECREF(vals);
3483 Py_XDECREF(keys);
3484 fail_0:
3485 PyMem_Free(path);
3486 return res;
3487}
3488#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003489#endif /* HAVE_SPAWNV */
3490
3491
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003492#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003493PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003494"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003495Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3496\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003497Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003498
3499static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003500posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003501{
Neal Norwitze241ce82003-02-17 18:17:05 +00003502 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003503 if (pid == -1)
3504 return posix_error();
3505 PyOS_AfterFork();
3506 return PyInt_FromLong((long)pid);
3507}
3508#endif
3509
3510
Guido van Rossumad0ee831995-03-01 10:34:45 +00003511#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003512PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003513"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003514Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003515Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003516
Barry Warsaw53699e91996-12-10 23:23:01 +00003517static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003518posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003519{
Neal Norwitze241ce82003-02-17 18:17:05 +00003520 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003521 if (pid == -1)
3522 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003523 if (pid == 0)
3524 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003525 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003526}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003527#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003528
Neal Norwitzb59798b2003-03-21 01:43:31 +00003529/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003530/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3531#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003532#define DEV_PTY_FILE "/dev/ptc"
3533#define HAVE_DEV_PTMX
3534#else
3535#define DEV_PTY_FILE "/dev/ptmx"
3536#endif
3537
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003538#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003539#ifdef HAVE_PTY_H
3540#include <pty.h>
3541#else
3542#ifdef HAVE_LIBUTIL_H
3543#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003544#endif /* HAVE_LIBUTIL_H */
3545#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003546#ifdef HAVE_STROPTS_H
3547#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003548#endif
3549#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003550
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003551#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003552PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003553"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003554Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003555
3556static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003557posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003558{
3559 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003560#ifndef HAVE_OPENPTY
3561 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003562#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003563#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003564 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003565#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003566 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003567#endif
3568#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003569
Thomas Wouters70c21a12000-07-14 14:28:33 +00003570#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003571 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3572 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003573#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003574 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3575 if (slave_name == NULL)
3576 return posix_error();
3577
3578 slave_fd = open(slave_name, O_RDWR);
3579 if (slave_fd < 0)
3580 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003581#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003582 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003583 if (master_fd < 0)
3584 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003585 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003586 /* change permission of slave */
3587 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003588 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003589 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003590 }
3591 /* unlock slave */
3592 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003593 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003594 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003595 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003596 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003597 slave_name = ptsname(master_fd); /* get name of slave */
3598 if (slave_name == NULL)
3599 return posix_error();
3600 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3601 if (slave_fd < 0)
3602 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003603#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003604 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3605 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003606#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003607 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003608#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003609#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003610#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003611
Fred Drake8cef4cf2000-06-28 16:40:38 +00003612 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003613
Fred Drake8cef4cf2000-06-28 16:40:38 +00003614}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003615#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003616
3617#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003618PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003619"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003620Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3621Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003622To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003623
3624static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003625posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003626{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003627 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003628
Fred Drake8cef4cf2000-06-28 16:40:38 +00003629 pid = forkpty(&master_fd, NULL, NULL, NULL);
3630 if (pid == -1)
3631 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003632 if (pid == 0)
3633 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003634 return Py_BuildValue("(ii)", pid, master_fd);
3635}
3636#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003637
Guido van Rossumad0ee831995-03-01 10:34:45 +00003638#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003639PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003640"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003641Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003642
Barry Warsaw53699e91996-12-10 23:23:01 +00003643static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003644posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003645{
Barry Warsaw53699e91996-12-10 23:23:01 +00003646 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003647}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003648#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003649
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003650
Guido van Rossumad0ee831995-03-01 10:34:45 +00003651#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003652PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003653"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003654Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003655
Barry Warsaw53699e91996-12-10 23:23:01 +00003656static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003657posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003658{
Barry Warsaw53699e91996-12-10 23:23:01 +00003659 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003660}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003661#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003662
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003663
Guido van Rossumad0ee831995-03-01 10:34:45 +00003664#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003665PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003666"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003667Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003668
Barry Warsaw53699e91996-12-10 23:23:01 +00003669static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003670posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003671{
Barry Warsaw53699e91996-12-10 23:23:01 +00003672 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003673}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003674#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003675
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003676
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003677PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003678"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003679Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003680
Barry Warsaw53699e91996-12-10 23:23:01 +00003681static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003682posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003683{
Barry Warsaw53699e91996-12-10 23:23:01 +00003684 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003685}
3686
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003687
Fred Drakec9680921999-12-13 16:37:25 +00003688#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003689PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003690"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003691Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003692
3693static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003694posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003695{
3696 PyObject *result = NULL;
3697
Fred Drakec9680921999-12-13 16:37:25 +00003698#ifdef NGROUPS_MAX
3699#define MAX_GROUPS NGROUPS_MAX
3700#else
3701 /* defined to be 16 on Solaris7, so this should be a small number */
3702#define MAX_GROUPS 64
3703#endif
3704 gid_t grouplist[MAX_GROUPS];
3705 int n;
3706
3707 n = getgroups(MAX_GROUPS, grouplist);
3708 if (n < 0)
3709 posix_error();
3710 else {
3711 result = PyList_New(n);
3712 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003713 int i;
3714 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003715 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003716 if (o == NULL) {
3717 Py_DECREF(result);
3718 result = NULL;
3719 break;
3720 }
3721 PyList_SET_ITEM(result, i, o);
3722 }
3723 }
3724 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003725
Fred Drakec9680921999-12-13 16:37:25 +00003726 return result;
3727}
3728#endif
3729
Martin v. Löwis606edc12002-06-13 21:09:11 +00003730#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003731PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003732"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003733Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003734
3735static PyObject *
3736posix_getpgid(PyObject *self, PyObject *args)
3737{
3738 int pid, pgid;
3739 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3740 return NULL;
3741 pgid = getpgid(pid);
3742 if (pgid < 0)
3743 return posix_error();
3744 return PyInt_FromLong((long)pgid);
3745}
3746#endif /* HAVE_GETPGID */
3747
3748
Guido van Rossumb6775db1994-08-01 11:34:53 +00003749#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003750PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003751"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003752Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003753
Barry Warsaw53699e91996-12-10 23:23:01 +00003754static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003755posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003756{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003757#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003758 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003759#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003760 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003761#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003762}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003763#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003764
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003765
Guido van Rossumb6775db1994-08-01 11:34:53 +00003766#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003767PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003768"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003769Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003770
Barry Warsaw53699e91996-12-10 23:23:01 +00003771static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003772posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003773{
Guido van Rossum64933891994-10-20 21:56:42 +00003774#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003775 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003776#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003777 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003778#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003779 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003780 Py_INCREF(Py_None);
3781 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003782}
3783
Guido van Rossumb6775db1994-08-01 11:34:53 +00003784#endif /* HAVE_SETPGRP */
3785
Guido van Rossumad0ee831995-03-01 10:34:45 +00003786#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003787PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003788"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003789Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003790
Barry Warsaw53699e91996-12-10 23:23:01 +00003791static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003792posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003793{
Barry Warsaw53699e91996-12-10 23:23:01 +00003794 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003795}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003796#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003797
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003798
Fred Drake12c6e2d1999-12-14 21:25:03 +00003799#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003800PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003801"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003802Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003803
3804static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003805posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003806{
Neal Norwitze241ce82003-02-17 18:17:05 +00003807 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003808 char *name;
3809 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003810
Fred Drakea30680b2000-12-06 21:24:28 +00003811 errno = 0;
3812 name = getlogin();
3813 if (name == NULL) {
3814 if (errno)
3815 posix_error();
3816 else
3817 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003818 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003819 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003820 else
3821 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003822 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003823
Fred Drake12c6e2d1999-12-14 21:25:03 +00003824 return result;
3825}
3826#endif
3827
Guido van Rossumad0ee831995-03-01 10:34:45 +00003828#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003829PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003830"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003831Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003832
Barry Warsaw53699e91996-12-10 23:23:01 +00003833static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003834posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003835{
Barry Warsaw53699e91996-12-10 23:23:01 +00003836 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003837}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003838#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003839
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003840
Guido van Rossumad0ee831995-03-01 10:34:45 +00003841#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003842PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003843"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003844Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003845
Barry Warsaw53699e91996-12-10 23:23:01 +00003846static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003847posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003848{
3849 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003850 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003851 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003852#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003853 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3854 APIRET rc;
3855 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003856 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003857
3858 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3859 APIRET rc;
3860 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003861 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003862
3863 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003864 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003865#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003866 if (kill(pid, sig) == -1)
3867 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003868#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003869 Py_INCREF(Py_None);
3870 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003871}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003872#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003873
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003874#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003875PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003876"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003877Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003878
3879static PyObject *
3880posix_killpg(PyObject *self, PyObject *args)
3881{
3882 int pgid, sig;
3883 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3884 return NULL;
3885 if (killpg(pgid, sig) == -1)
3886 return posix_error();
3887 Py_INCREF(Py_None);
3888 return Py_None;
3889}
3890#endif
3891
Guido van Rossumc0125471996-06-28 18:55:32 +00003892#ifdef HAVE_PLOCK
3893
3894#ifdef HAVE_SYS_LOCK_H
3895#include <sys/lock.h>
3896#endif
3897
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003898PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003899"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003900Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003901
Barry Warsaw53699e91996-12-10 23:23:01 +00003902static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003903posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003904{
3905 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003906 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003907 return NULL;
3908 if (plock(op) == -1)
3909 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003910 Py_INCREF(Py_None);
3911 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003912}
3913#endif
3914
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003915
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003916#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003917PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003918"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003919Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003920
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003921#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003922#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003923static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003924async_system(const char *command)
3925{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003926 char errormsg[256], args[1024];
3927 RESULTCODES rcodes;
3928 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003929
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003930 char *shell = getenv("COMSPEC");
3931 if (!shell)
3932 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003933
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003934 /* avoid overflowing the argument buffer */
3935 if (strlen(shell) + 3 + strlen(command) >= 1024)
3936 return ERROR_NOT_ENOUGH_MEMORY
3937
3938 args[0] = '\0';
3939 strcat(args, shell);
3940 strcat(args, "/c ");
3941 strcat(args, command);
3942
3943 /* execute asynchronously, inheriting the environment */
3944 rc = DosExecPgm(errormsg,
3945 sizeof(errormsg),
3946 EXEC_ASYNC,
3947 args,
3948 NULL,
3949 &rcodes,
3950 shell);
3951 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003952}
3953
Guido van Rossumd48f2521997-12-05 22:19:34 +00003954static FILE *
3955popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003956{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003957 int oldfd, tgtfd;
3958 HFILE pipeh[2];
3959 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003960
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003961 /* mode determines which of stdin or stdout is reconnected to
3962 * the pipe to the child
3963 */
3964 if (strchr(mode, 'r') != NULL) {
3965 tgt_fd = 1; /* stdout */
3966 } else if (strchr(mode, 'w')) {
3967 tgt_fd = 0; /* stdin */
3968 } else {
3969 *err = ERROR_INVALID_ACCESS;
3970 return NULL;
3971 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003972
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003973 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003974 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3975 *err = rc;
3976 return NULL;
3977 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003978
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003979 /* prevent other threads accessing stdio */
3980 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003981
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003982 /* reconnect stdio and execute child */
3983 oldfd = dup(tgtfd);
3984 close(tgtfd);
3985 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3986 DosClose(pipeh[tgtfd]);
3987 rc = async_system(command);
3988 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003989
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003990 /* restore stdio */
3991 dup2(oldfd, tgtfd);
3992 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003993
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003994 /* allow other threads access to stdio */
3995 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003996
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003997 /* if execution of child was successful return file stream */
3998 if (rc == NO_ERROR)
3999 return fdopen(pipeh[1 - tgtfd], mode);
4000 else {
4001 DosClose(pipeh[1 - tgtfd]);
4002 *err = rc;
4003 return NULL;
4004 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004005}
4006
4007static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004008posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004009{
4010 char *name;
4011 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00004012 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004013 FILE *fp;
4014 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004015 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004016 return NULL;
4017 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00004018 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004019 Py_END_ALLOW_THREADS
4020 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004021 return os2_error(err);
4022
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004023 f = PyFile_FromFile(fp, name, mode, fclose);
4024 if (f != NULL)
4025 PyFile_SetBufSize(f, bufsize);
4026 return f;
4027}
4028
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004029#elif defined(PYCC_GCC)
4030
4031/* standard posix version of popen() support */
4032static PyObject *
4033posix_popen(PyObject *self, PyObject *args)
4034{
4035 char *name;
4036 char *mode = "r";
4037 int bufsize = -1;
4038 FILE *fp;
4039 PyObject *f;
4040 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4041 return NULL;
4042 Py_BEGIN_ALLOW_THREADS
4043 fp = popen(name, mode);
4044 Py_END_ALLOW_THREADS
4045 if (fp == NULL)
4046 return posix_error();
4047 f = PyFile_FromFile(fp, name, mode, pclose);
4048 if (f != NULL)
4049 PyFile_SetBufSize(f, bufsize);
4050 return f;
4051}
4052
4053/* fork() under OS/2 has lots'o'warts
4054 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4055 * most of this code is a ripoff of the win32 code, but using the
4056 * capabilities of EMX's C library routines
4057 */
4058
4059/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4060#define POPEN_1 1
4061#define POPEN_2 2
4062#define POPEN_3 3
4063#define POPEN_4 4
4064
4065static PyObject *_PyPopen(char *, int, int, int);
4066static int _PyPclose(FILE *file);
4067
4068/*
4069 * Internal dictionary mapping popen* file pointers to process handles,
4070 * for use when retrieving the process exit code. See _PyPclose() below
4071 * for more information on this dictionary's use.
4072 */
4073static PyObject *_PyPopenProcs = NULL;
4074
4075/* os2emx version of popen2()
4076 *
4077 * The result of this function is a pipe (file) connected to the
4078 * process's stdin, and a pipe connected to the process's stdout.
4079 */
4080
4081static PyObject *
4082os2emx_popen2(PyObject *self, PyObject *args)
4083{
4084 PyObject *f;
4085 int tm=0;
4086
4087 char *cmdstring;
4088 char *mode = "t";
4089 int bufsize = -1;
4090 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4091 return NULL;
4092
4093 if (*mode == 't')
4094 tm = O_TEXT;
4095 else if (*mode != 'b') {
4096 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4097 return NULL;
4098 } else
4099 tm = O_BINARY;
4100
4101 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4102
4103 return f;
4104}
4105
4106/*
4107 * Variation on os2emx.popen2
4108 *
4109 * The result of this function is 3 pipes - the process's stdin,
4110 * stdout and stderr
4111 */
4112
4113static PyObject *
4114os2emx_popen3(PyObject *self, PyObject *args)
4115{
4116 PyObject *f;
4117 int tm = 0;
4118
4119 char *cmdstring;
4120 char *mode = "t";
4121 int bufsize = -1;
4122 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4123 return NULL;
4124
4125 if (*mode == 't')
4126 tm = O_TEXT;
4127 else if (*mode != 'b') {
4128 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4129 return NULL;
4130 } else
4131 tm = O_BINARY;
4132
4133 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4134
4135 return f;
4136}
4137
4138/*
4139 * Variation on os2emx.popen2
4140 *
Tim Peters11b23062003-04-23 02:39:17 +00004141 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004142 * and stdout+stderr combined as a single pipe.
4143 */
4144
4145static PyObject *
4146os2emx_popen4(PyObject *self, PyObject *args)
4147{
4148 PyObject *f;
4149 int tm = 0;
4150
4151 char *cmdstring;
4152 char *mode = "t";
4153 int bufsize = -1;
4154 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4155 return NULL;
4156
4157 if (*mode == 't')
4158 tm = O_TEXT;
4159 else if (*mode != 'b') {
4160 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4161 return NULL;
4162 } else
4163 tm = O_BINARY;
4164
4165 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4166
4167 return f;
4168}
4169
4170/* a couple of structures for convenient handling of multiple
4171 * file handles and pipes
4172 */
4173struct file_ref
4174{
4175 int handle;
4176 int flags;
4177};
4178
4179struct pipe_ref
4180{
4181 int rd;
4182 int wr;
4183};
4184
4185/* The following code is derived from the win32 code */
4186
4187static PyObject *
4188_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4189{
4190 struct file_ref stdio[3];
4191 struct pipe_ref p_fd[3];
4192 FILE *p_s[3];
4193 int file_count, i, pipe_err, pipe_pid;
4194 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4195 PyObject *f, *p_f[3];
4196
4197 /* file modes for subsequent fdopen's on pipe handles */
4198 if (mode == O_TEXT)
4199 {
4200 rd_mode = "rt";
4201 wr_mode = "wt";
4202 }
4203 else
4204 {
4205 rd_mode = "rb";
4206 wr_mode = "wb";
4207 }
4208
4209 /* prepare shell references */
4210 if ((shell = getenv("EMXSHELL")) == NULL)
4211 if ((shell = getenv("COMSPEC")) == NULL)
4212 {
4213 errno = ENOENT;
4214 return posix_error();
4215 }
4216
4217 sh_name = _getname(shell);
4218 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4219 opt = "/c";
4220 else
4221 opt = "-c";
4222
4223 /* save current stdio fds + their flags, and set not inheritable */
4224 i = pipe_err = 0;
4225 while (pipe_err >= 0 && i < 3)
4226 {
4227 pipe_err = stdio[i].handle = dup(i);
4228 stdio[i].flags = fcntl(i, F_GETFD, 0);
4229 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4230 i++;
4231 }
4232 if (pipe_err < 0)
4233 {
4234 /* didn't get them all saved - clean up and bail out */
4235 int saved_err = errno;
4236 while (i-- > 0)
4237 {
4238 close(stdio[i].handle);
4239 }
4240 errno = saved_err;
4241 return posix_error();
4242 }
4243
4244 /* create pipe ends */
4245 file_count = 2;
4246 if (n == POPEN_3)
4247 file_count = 3;
4248 i = pipe_err = 0;
4249 while ((pipe_err == 0) && (i < file_count))
4250 pipe_err = pipe((int *)&p_fd[i++]);
4251 if (pipe_err < 0)
4252 {
4253 /* didn't get them all made - clean up and bail out */
4254 while (i-- > 0)
4255 {
4256 close(p_fd[i].wr);
4257 close(p_fd[i].rd);
4258 }
4259 errno = EPIPE;
4260 return posix_error();
4261 }
4262
4263 /* change the actual standard IO streams over temporarily,
4264 * making the retained pipe ends non-inheritable
4265 */
4266 pipe_err = 0;
4267
4268 /* - stdin */
4269 if (dup2(p_fd[0].rd, 0) == 0)
4270 {
4271 close(p_fd[0].rd);
4272 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4273 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4274 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4275 {
4276 close(p_fd[0].wr);
4277 pipe_err = -1;
4278 }
4279 }
4280 else
4281 {
4282 pipe_err = -1;
4283 }
4284
4285 /* - stdout */
4286 if (pipe_err == 0)
4287 {
4288 if (dup2(p_fd[1].wr, 1) == 1)
4289 {
4290 close(p_fd[1].wr);
4291 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4292 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4293 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4294 {
4295 close(p_fd[1].rd);
4296 pipe_err = -1;
4297 }
4298 }
4299 else
4300 {
4301 pipe_err = -1;
4302 }
4303 }
4304
4305 /* - stderr, as required */
4306 if (pipe_err == 0)
4307 switch (n)
4308 {
4309 case POPEN_3:
4310 {
4311 if (dup2(p_fd[2].wr, 2) == 2)
4312 {
4313 close(p_fd[2].wr);
4314 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4315 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4316 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4317 {
4318 close(p_fd[2].rd);
4319 pipe_err = -1;
4320 }
4321 }
4322 else
4323 {
4324 pipe_err = -1;
4325 }
4326 break;
4327 }
4328
4329 case POPEN_4:
4330 {
4331 if (dup2(1, 2) != 2)
4332 {
4333 pipe_err = -1;
4334 }
4335 break;
4336 }
4337 }
4338
4339 /* spawn the child process */
4340 if (pipe_err == 0)
4341 {
4342 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4343 if (pipe_pid == -1)
4344 {
4345 pipe_err = -1;
4346 }
4347 else
4348 {
4349 /* save the PID into the FILE structure
4350 * NOTE: this implementation doesn't actually
4351 * take advantage of this, but do it for
4352 * completeness - AIM Apr01
4353 */
4354 for (i = 0; i < file_count; i++)
4355 p_s[i]->_pid = pipe_pid;
4356 }
4357 }
4358
4359 /* reset standard IO to normal */
4360 for (i = 0; i < 3; i++)
4361 {
4362 dup2(stdio[i].handle, i);
4363 fcntl(i, F_SETFD, stdio[i].flags);
4364 close(stdio[i].handle);
4365 }
4366
4367 /* if any remnant problems, clean up and bail out */
4368 if (pipe_err < 0)
4369 {
4370 for (i = 0; i < 3; i++)
4371 {
4372 close(p_fd[i].rd);
4373 close(p_fd[i].wr);
4374 }
4375 errno = EPIPE;
4376 return posix_error_with_filename(cmdstring);
4377 }
4378
4379 /* build tuple of file objects to return */
4380 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4381 PyFile_SetBufSize(p_f[0], bufsize);
4382 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4383 PyFile_SetBufSize(p_f[1], bufsize);
4384 if (n == POPEN_3)
4385 {
4386 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4387 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004388 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004389 }
4390 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004391 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004392
4393 /*
4394 * Insert the files we've created into the process dictionary
4395 * all referencing the list with the process handle and the
4396 * initial number of files (see description below in _PyPclose).
4397 * Since if _PyPclose later tried to wait on a process when all
4398 * handles weren't closed, it could create a deadlock with the
4399 * child, we spend some energy here to try to ensure that we
4400 * either insert all file handles into the dictionary or none
4401 * at all. It's a little clumsy with the various popen modes
4402 * and variable number of files involved.
4403 */
4404 if (!_PyPopenProcs)
4405 {
4406 _PyPopenProcs = PyDict_New();
4407 }
4408
4409 if (_PyPopenProcs)
4410 {
4411 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4412 int ins_rc[3];
4413
4414 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4415 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4416
4417 procObj = PyList_New(2);
4418 pidObj = PyInt_FromLong((long) pipe_pid);
4419 intObj = PyInt_FromLong((long) file_count);
4420
4421 if (procObj && pidObj && intObj)
4422 {
4423 PyList_SetItem(procObj, 0, pidObj);
4424 PyList_SetItem(procObj, 1, intObj);
4425
4426 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4427 if (fileObj[0])
4428 {
4429 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4430 fileObj[0],
4431 procObj);
4432 }
4433 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4434 if (fileObj[1])
4435 {
4436 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4437 fileObj[1],
4438 procObj);
4439 }
4440 if (file_count >= 3)
4441 {
4442 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4443 if (fileObj[2])
4444 {
4445 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4446 fileObj[2],
4447 procObj);
4448 }
4449 }
4450
4451 if (ins_rc[0] < 0 || !fileObj[0] ||
4452 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4453 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4454 {
4455 /* Something failed - remove any dictionary
4456 * entries that did make it.
4457 */
4458 if (!ins_rc[0] && fileObj[0])
4459 {
4460 PyDict_DelItem(_PyPopenProcs,
4461 fileObj[0]);
4462 }
4463 if (!ins_rc[1] && fileObj[1])
4464 {
4465 PyDict_DelItem(_PyPopenProcs,
4466 fileObj[1]);
4467 }
4468 if (!ins_rc[2] && fileObj[2])
4469 {
4470 PyDict_DelItem(_PyPopenProcs,
4471 fileObj[2]);
4472 }
4473 }
4474 }
Tim Peters11b23062003-04-23 02:39:17 +00004475
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004476 /*
4477 * Clean up our localized references for the dictionary keys
4478 * and value since PyDict_SetItem will Py_INCREF any copies
4479 * that got placed in the dictionary.
4480 */
4481 Py_XDECREF(procObj);
4482 Py_XDECREF(fileObj[0]);
4483 Py_XDECREF(fileObj[1]);
4484 Py_XDECREF(fileObj[2]);
4485 }
4486
4487 /* Child is launched. */
4488 return f;
4489}
4490
4491/*
4492 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4493 * exit code for the child process and return as a result of the close.
4494 *
4495 * This function uses the _PyPopenProcs dictionary in order to map the
4496 * input file pointer to information about the process that was
4497 * originally created by the popen* call that created the file pointer.
4498 * The dictionary uses the file pointer as a key (with one entry
4499 * inserted for each file returned by the original popen* call) and a
4500 * single list object as the value for all files from a single call.
4501 * The list object contains the Win32 process handle at [0], and a file
4502 * count at [1], which is initialized to the total number of file
4503 * handles using that list.
4504 *
4505 * This function closes whichever handle it is passed, and decrements
4506 * the file count in the dictionary for the process handle pointed to
4507 * by this file. On the last close (when the file count reaches zero),
4508 * this function will wait for the child process and then return its
4509 * exit code as the result of the close() operation. This permits the
4510 * files to be closed in any order - it is always the close() of the
4511 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004512 *
4513 * NOTE: This function is currently called with the GIL released.
4514 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004515 */
4516
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004517static int _PyPclose(FILE *file)
4518{
4519 int result;
4520 int exit_code;
4521 int pipe_pid;
4522 PyObject *procObj, *pidObj, *intObj, *fileObj;
4523 int file_count;
4524#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004525 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004526#endif
4527
4528 /* Close the file handle first, to ensure it can't block the
4529 * child from exiting if it's the last handle.
4530 */
4531 result = fclose(file);
4532
4533#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004534 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004535#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004536 if (_PyPopenProcs)
4537 {
4538 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4539 (procObj = PyDict_GetItem(_PyPopenProcs,
4540 fileObj)) != NULL &&
4541 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4542 (intObj = PyList_GetItem(procObj,1)) != NULL)
4543 {
4544 pipe_pid = (int) PyInt_AsLong(pidObj);
4545 file_count = (int) PyInt_AsLong(intObj);
4546
4547 if (file_count > 1)
4548 {
4549 /* Still other files referencing process */
4550 file_count--;
4551 PyList_SetItem(procObj,1,
4552 PyInt_FromLong((long) file_count));
4553 }
4554 else
4555 {
4556 /* Last file for this process */
4557 if (result != EOF &&
4558 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4559 {
4560 /* extract exit status */
4561 if (WIFEXITED(exit_code))
4562 {
4563 result = WEXITSTATUS(exit_code);
4564 }
4565 else
4566 {
4567 errno = EPIPE;
4568 result = -1;
4569 }
4570 }
4571 else
4572 {
4573 /* Indicate failure - this will cause the file object
4574 * to raise an I/O error and translate the last
4575 * error code from errno. We do have a problem with
4576 * last errors that overlap the normal errno table,
4577 * but that's a consistent problem with the file object.
4578 */
4579 result = -1;
4580 }
4581 }
4582
4583 /* Remove this file pointer from dictionary */
4584 PyDict_DelItem(_PyPopenProcs, fileObj);
4585
4586 if (PyDict_Size(_PyPopenProcs) == 0)
4587 {
4588 Py_DECREF(_PyPopenProcs);
4589 _PyPopenProcs = NULL;
4590 }
4591
4592 } /* if object retrieval ok */
4593
4594 Py_XDECREF(fileObj);
4595 } /* if _PyPopenProcs */
4596
4597#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004598 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004599#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004600 return result;
4601}
4602
4603#endif /* PYCC_??? */
4604
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004605#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004606
4607/*
4608 * Portable 'popen' replacement for Win32.
4609 *
4610 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4611 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004612 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004613 */
4614
4615#include <malloc.h>
4616#include <io.h>
4617#include <fcntl.h>
4618
4619/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4620#define POPEN_1 1
4621#define POPEN_2 2
4622#define POPEN_3 3
4623#define POPEN_4 4
4624
4625static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004626static int _PyPclose(FILE *file);
4627
4628/*
4629 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004630 * for use when retrieving the process exit code. See _PyPclose() below
4631 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004632 */
4633static PyObject *_PyPopenProcs = NULL;
4634
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004635
4636/* popen that works from a GUI.
4637 *
4638 * The result of this function is a pipe (file) connected to the
4639 * processes stdin or stdout, depending on the requested mode.
4640 */
4641
4642static PyObject *
4643posix_popen(PyObject *self, PyObject *args)
4644{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004645 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004646 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004647
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004648 char *cmdstring;
4649 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004650 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004651 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004652 return NULL;
4653
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004654 if (*mode == 'r')
4655 tm = _O_RDONLY;
4656 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004657 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004658 return NULL;
4659 } else
4660 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004661
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004662 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004663 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004664 return NULL;
4665 }
4666
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004667 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004668 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004669 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004670 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004671 else
4672 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4673
4674 return f;
4675}
4676
4677/* Variation on win32pipe.popen
4678 *
4679 * The result of this function is a pipe (file) connected to the
4680 * process's stdin, and a pipe connected to the process's stdout.
4681 */
4682
4683static PyObject *
4684win32_popen2(PyObject *self, PyObject *args)
4685{
4686 PyObject *f;
4687 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004688
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004689 char *cmdstring;
4690 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004691 int bufsize = -1;
4692 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004693 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004694
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004695 if (*mode == 't')
4696 tm = _O_TEXT;
4697 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004698 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004699 return NULL;
4700 } else
4701 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004702
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004703 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004704 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004705 return NULL;
4706 }
4707
4708 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004709
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004710 return f;
4711}
4712
4713/*
4714 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004715 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004716 * The result of this function is 3 pipes - the process's stdin,
4717 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004718 */
4719
4720static PyObject *
4721win32_popen3(PyObject *self, PyObject *args)
4722{
4723 PyObject *f;
4724 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004725
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004726 char *cmdstring;
4727 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004728 int bufsize = -1;
4729 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004730 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004731
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004732 if (*mode == 't')
4733 tm = _O_TEXT;
4734 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004735 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004736 return NULL;
4737 } else
4738 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004739
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004740 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004741 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004742 return NULL;
4743 }
4744
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004745 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004746
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004747 return f;
4748}
4749
4750/*
4751 * Variation on win32pipe.popen
4752 *
Tim Peters5aa91602002-01-30 05:46:57 +00004753 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004754 * and stdout+stderr combined as a single pipe.
4755 */
4756
4757static PyObject *
4758win32_popen4(PyObject *self, PyObject *args)
4759{
4760 PyObject *f;
4761 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004762
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004763 char *cmdstring;
4764 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004765 int bufsize = -1;
4766 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004767 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004768
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004769 if (*mode == 't')
4770 tm = _O_TEXT;
4771 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004772 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004773 return NULL;
4774 } else
4775 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004776
4777 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004778 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004779 return NULL;
4780 }
4781
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004782 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004783
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004784 return f;
4785}
4786
Mark Hammond08501372001-01-31 07:30:29 +00004787static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004788_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004789 HANDLE hStdin,
4790 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004791 HANDLE hStderr,
4792 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004793{
4794 PROCESS_INFORMATION piProcInfo;
4795 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004796 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004797 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004798 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004799 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004800 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004801
4802 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004803 char *comshell;
4804
Tim Peters92e4dd82002-10-05 01:47:34 +00004805 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004806 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004807 /* x < i, so x fits into an integer */
4808 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004809
4810 /* Explicitly check if we are using COMMAND.COM. If we are
4811 * then use the w9xpopen hack.
4812 */
4813 comshell = s1 + x;
4814 while (comshell >= s1 && *comshell != '\\')
4815 --comshell;
4816 ++comshell;
4817
4818 if (GetVersion() < 0x80000000 &&
4819 _stricmp(comshell, "command.com") != 0) {
4820 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004821 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004822 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004823 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004824 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004825 }
4826 else {
4827 /*
Tim Peters402d5982001-08-27 06:37:48 +00004828 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4829 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004830 */
Mark Hammond08501372001-01-31 07:30:29 +00004831 char modulepath[_MAX_PATH];
4832 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004833 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Thomas Wouters477c8d52006-05-27 19:21:47 +00004834 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004835 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004836 x = i+1;
4837 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004838 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004839 strncat(modulepath,
4840 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004841 (sizeof(modulepath)/sizeof(modulepath[0]))
4842 -strlen(modulepath));
4843 if (stat(modulepath, &statinfo) != 0) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00004844 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
Tim Peters5aa91602002-01-30 05:46:57 +00004845 /* Eeek - file-not-found - possibly an embedding
4846 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004847 */
Tim Peters5aa91602002-01-30 05:46:57 +00004848 strncpy(modulepath,
4849 Py_GetExecPrefix(),
Guido van Rossumd8faa362007-04-27 19:54:29 +00004850 mplen);
4851 modulepath[mplen-1] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004852 if (modulepath[strlen(modulepath)-1] != '\\')
4853 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004854 strncat(modulepath,
4855 szConsoleSpawn,
Guido van Rossumd8faa362007-04-27 19:54:29 +00004856 mplen-strlen(modulepath));
Mark Hammond08501372001-01-31 07:30:29 +00004857 /* No where else to look - raise an easily identifiable
4858 error, rather than leaving Windows to report
4859 "file not found" - as the user is probably blissfully
4860 unaware this shim EXE is used, and it will confuse them.
4861 (well, it confused me for a while ;-)
4862 */
4863 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004864 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004865 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004866 "for popen to work with your shell "
4867 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004868 szConsoleSpawn);
4869 return FALSE;
4870 }
4871 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004872 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004873 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004874 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004875
Tim Peters92e4dd82002-10-05 01:47:34 +00004876 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004877 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004878 /* To maintain correct argument passing semantics,
4879 we pass the command-line as it stands, and allow
4880 quoting to be applied. w9xpopen.exe will then
4881 use its argv vector, and re-quote the necessary
4882 args for the ultimate child process.
4883 */
Tim Peters75cdad52001-11-28 22:07:30 +00004884 PyOS_snprintf(
4885 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004886 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004887 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004888 s1,
4889 s3,
4890 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004891 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004892 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004893 dialog:
4894 "Your program accessed mem currently in use at xxx"
4895 and a hopeful warning about the stability of your
4896 system.
4897 Cost is Ctrl+C wont kill children, but anyone
4898 who cares can have a go!
4899 */
4900 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004901 }
4902 }
4903
4904 /* Could be an else here to try cmd.exe / command.com in the path
4905 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004906 else {
Tim Peters402d5982001-08-27 06:37:48 +00004907 PyErr_SetString(PyExc_RuntimeError,
4908 "Cannot locate a COMSPEC environment variable to "
4909 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004910 return FALSE;
4911 }
Tim Peters5aa91602002-01-30 05:46:57 +00004912
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004913 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4914 siStartInfo.cb = sizeof(STARTUPINFO);
4915 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4916 siStartInfo.hStdInput = hStdin;
4917 siStartInfo.hStdOutput = hStdout;
4918 siStartInfo.hStdError = hStderr;
4919 siStartInfo.wShowWindow = SW_HIDE;
4920
4921 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004922 s2,
4923 NULL,
4924 NULL,
4925 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004926 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004927 NULL,
4928 NULL,
4929 &siStartInfo,
4930 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004931 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004932 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004933
Mark Hammondb37a3732000-08-14 04:47:33 +00004934 /* Return process handle */
4935 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004936 return TRUE;
4937 }
Tim Peters402d5982001-08-27 06:37:48 +00004938 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004939 return FALSE;
4940}
4941
4942/* The following code is based off of KB: Q190351 */
4943
4944static PyObject *
4945_PyPopen(char *cmdstring, int mode, int n)
4946{
4947 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4948 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004949 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004950
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004951 SECURITY_ATTRIBUTES saAttr;
4952 BOOL fSuccess;
4953 int fd1, fd2, fd3;
4954 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004955 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004956 PyObject *f;
4957
4958 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4959 saAttr.bInheritHandle = TRUE;
4960 saAttr.lpSecurityDescriptor = NULL;
4961
4962 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4963 return win32_error("CreatePipe", NULL);
4964
4965 /* Create new output read handle and the input write handle. Set
4966 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004967 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004968 * being created. */
4969 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004970 GetCurrentProcess(), &hChildStdinWrDup, 0,
4971 FALSE,
4972 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004973 if (!fSuccess)
4974 return win32_error("DuplicateHandle", NULL);
4975
4976 /* Close the inheritable version of ChildStdin
4977 that we're using. */
4978 CloseHandle(hChildStdinWr);
4979
4980 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4981 return win32_error("CreatePipe", NULL);
4982
4983 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004984 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4985 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004986 if (!fSuccess)
4987 return win32_error("DuplicateHandle", NULL);
4988
4989 /* Close the inheritable version of ChildStdout
4990 that we're using. */
4991 CloseHandle(hChildStdoutRd);
4992
4993 if (n != POPEN_4) {
4994 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4995 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004996 fSuccess = DuplicateHandle(GetCurrentProcess(),
4997 hChildStderrRd,
4998 GetCurrentProcess(),
4999 &hChildStderrRdDup, 0,
5000 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005001 if (!fSuccess)
5002 return win32_error("DuplicateHandle", NULL);
5003 /* Close the inheritable version of ChildStdErr that we're using. */
5004 CloseHandle(hChildStderrRd);
5005 }
Tim Peters5aa91602002-01-30 05:46:57 +00005006
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005007 switch (n) {
5008 case POPEN_1:
5009 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5010 case _O_WRONLY | _O_TEXT:
5011 /* Case for writing to child Stdin in text mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00005012 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005013 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005014 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005015 PyFile_SetBufSize(f, 0);
5016 /* We don't care about these pipes anymore, so close them. */
5017 CloseHandle(hChildStdoutRdDup);
5018 CloseHandle(hChildStderrRdDup);
5019 break;
5020
5021 case _O_RDONLY | _O_TEXT:
5022 /* Case for reading from child Stdout in text mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00005023 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005024 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005025 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005026 PyFile_SetBufSize(f, 0);
5027 /* We don't care about these pipes anymore, so close them. */
5028 CloseHandle(hChildStdinWrDup);
5029 CloseHandle(hChildStderrRdDup);
5030 break;
5031
5032 case _O_RDONLY | _O_BINARY:
5033 /* Case for readinig from child Stdout in binary mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00005034 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005035 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005036 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005037 PyFile_SetBufSize(f, 0);
5038 /* We don't care about these pipes anymore, so close them. */
5039 CloseHandle(hChildStdinWrDup);
5040 CloseHandle(hChildStderrRdDup);
5041 break;
5042
5043 case _O_WRONLY | _O_BINARY:
5044 /* Case for writing to child Stdin in binary mode. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00005045 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005046 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005047 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005048 PyFile_SetBufSize(f, 0);
5049 /* We don't care about these pipes anymore, so close them. */
5050 CloseHandle(hChildStdoutRdDup);
5051 CloseHandle(hChildStderrRdDup);
5052 break;
5053 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005054 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005055 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005056
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005057 case POPEN_2:
5058 case POPEN_4:
5059 {
5060 char *m1, *m2;
5061 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005062
Tim Peters7dca21e2002-08-19 00:42:29 +00005063 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005064 m1 = "r";
5065 m2 = "w";
5066 } else {
5067 m1 = "rb";
5068 m2 = "wb";
5069 }
5070
Thomas Wouters477c8d52006-05-27 19:21:47 +00005071 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005072 f1 = _fdopen(fd1, m2);
Thomas Wouters477c8d52006-05-27 19:21:47 +00005073 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005074 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005075 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005076 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005077 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005078 PyFile_SetBufSize(p2, 0);
5079
5080 if (n != 4)
5081 CloseHandle(hChildStderrRdDup);
5082
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005083 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005084 Py_XDECREF(p1);
5085 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005086 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005087 break;
5088 }
Tim Peters5aa91602002-01-30 05:46:57 +00005089
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005090 case POPEN_3:
5091 {
5092 char *m1, *m2;
5093 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005094
Tim Peters7dca21e2002-08-19 00:42:29 +00005095 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005096 m1 = "r";
5097 m2 = "w";
5098 } else {
5099 m1 = "rb";
5100 m2 = "wb";
5101 }
5102
Thomas Wouters477c8d52006-05-27 19:21:47 +00005103 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005104 f1 = _fdopen(fd1, m2);
Thomas Wouters477c8d52006-05-27 19:21:47 +00005105 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005106 f2 = _fdopen(fd2, m1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00005107 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005108 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005109 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005110 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5111 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005112 PyFile_SetBufSize(p1, 0);
5113 PyFile_SetBufSize(p2, 0);
5114 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005115 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005116 Py_XDECREF(p1);
5117 Py_XDECREF(p2);
5118 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005119 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005120 break;
5121 }
5122 }
5123
5124 if (n == POPEN_4) {
5125 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005126 hChildStdinRd,
5127 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005128 hChildStdoutWr,
5129 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005130 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005131 }
5132 else {
5133 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005134 hChildStdinRd,
5135 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005136 hChildStderrWr,
5137 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005138 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005139 }
5140
Mark Hammondb37a3732000-08-14 04:47:33 +00005141 /*
5142 * Insert the files we've created into the process dictionary
5143 * all referencing the list with the process handle and the
5144 * initial number of files (see description below in _PyPclose).
5145 * Since if _PyPclose later tried to wait on a process when all
5146 * handles weren't closed, it could create a deadlock with the
5147 * child, we spend some energy here to try to ensure that we
5148 * either insert all file handles into the dictionary or none
5149 * at all. It's a little clumsy with the various popen modes
5150 * and variable number of files involved.
5151 */
5152 if (!_PyPopenProcs) {
5153 _PyPopenProcs = PyDict_New();
5154 }
5155
5156 if (_PyPopenProcs) {
5157 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5158 int ins_rc[3];
5159
5160 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5161 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5162
5163 procObj = PyList_New(2);
5164 hProcessObj = PyLong_FromVoidPtr(hProcess);
5165 intObj = PyInt_FromLong(file_count);
5166
5167 if (procObj && hProcessObj && intObj) {
5168 PyList_SetItem(procObj,0,hProcessObj);
5169 PyList_SetItem(procObj,1,intObj);
5170
5171 fileObj[0] = PyLong_FromVoidPtr(f1);
5172 if (fileObj[0]) {
5173 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5174 fileObj[0],
5175 procObj);
5176 }
5177 if (file_count >= 2) {
5178 fileObj[1] = PyLong_FromVoidPtr(f2);
5179 if (fileObj[1]) {
5180 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5181 fileObj[1],
5182 procObj);
5183 }
5184 }
5185 if (file_count >= 3) {
5186 fileObj[2] = PyLong_FromVoidPtr(f3);
5187 if (fileObj[2]) {
5188 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5189 fileObj[2],
5190 procObj);
5191 }
5192 }
5193
5194 if (ins_rc[0] < 0 || !fileObj[0] ||
5195 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5196 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5197 /* Something failed - remove any dictionary
5198 * entries that did make it.
5199 */
5200 if (!ins_rc[0] && fileObj[0]) {
5201 PyDict_DelItem(_PyPopenProcs,
5202 fileObj[0]);
5203 }
5204 if (!ins_rc[1] && fileObj[1]) {
5205 PyDict_DelItem(_PyPopenProcs,
5206 fileObj[1]);
5207 }
5208 if (!ins_rc[2] && fileObj[2]) {
5209 PyDict_DelItem(_PyPopenProcs,
5210 fileObj[2]);
5211 }
5212 }
5213 }
Tim Peters5aa91602002-01-30 05:46:57 +00005214
Mark Hammondb37a3732000-08-14 04:47:33 +00005215 /*
5216 * Clean up our localized references for the dictionary keys
5217 * and value since PyDict_SetItem will Py_INCREF any copies
5218 * that got placed in the dictionary.
5219 */
5220 Py_XDECREF(procObj);
5221 Py_XDECREF(fileObj[0]);
5222 Py_XDECREF(fileObj[1]);
5223 Py_XDECREF(fileObj[2]);
5224 }
5225
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005226 /* Child is launched. Close the parents copy of those pipe
5227 * handles that only the child should have open. You need to
5228 * make sure that no handles to the write end of the output pipe
5229 * are maintained in this process or else the pipe will not close
5230 * when the child process exits and the ReadFile will hang. */
5231
5232 if (!CloseHandle(hChildStdinRd))
5233 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005234
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005235 if (!CloseHandle(hChildStdoutWr))
5236 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005237
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005238 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5239 return win32_error("CloseHandle", NULL);
5240
5241 return f;
5242}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005243
5244/*
5245 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5246 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005247 *
5248 * This function uses the _PyPopenProcs dictionary in order to map the
5249 * input file pointer to information about the process that was
5250 * originally created by the popen* call that created the file pointer.
5251 * The dictionary uses the file pointer as a key (with one entry
5252 * inserted for each file returned by the original popen* call) and a
5253 * single list object as the value for all files from a single call.
5254 * The list object contains the Win32 process handle at [0], and a file
5255 * count at [1], which is initialized to the total number of file
5256 * handles using that list.
5257 *
5258 * This function closes whichever handle it is passed, and decrements
5259 * the file count in the dictionary for the process handle pointed to
5260 * by this file. On the last close (when the file count reaches zero),
5261 * this function will wait for the child process and then return its
5262 * exit code as the result of the close() operation. This permits the
5263 * files to be closed in any order - it is always the close() of the
5264 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005265 *
5266 * NOTE: This function is currently called with the GIL released.
5267 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005268 */
Tim Peters736aa322000-09-01 06:51:24 +00005269
Fredrik Lundh56055a42000-07-23 19:47:12 +00005270static int _PyPclose(FILE *file)
5271{
Fredrik Lundh20318932000-07-26 17:29:12 +00005272 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005273 DWORD exit_code;
5274 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005275 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5276 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005277#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005278 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005279#endif
5280
Fredrik Lundh20318932000-07-26 17:29:12 +00005281 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005282 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005283 */
5284 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005285#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005286 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005287#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005288 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005289 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5290 (procObj = PyDict_GetItem(_PyPopenProcs,
5291 fileObj)) != NULL &&
5292 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5293 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5294
5295 hProcess = PyLong_AsVoidPtr(hProcessObj);
5296 file_count = PyInt_AsLong(intObj);
5297
5298 if (file_count > 1) {
5299 /* Still other files referencing process */
5300 file_count--;
5301 PyList_SetItem(procObj,1,
5302 PyInt_FromLong(file_count));
5303 } else {
5304 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005305 if (result != EOF &&
5306 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5307 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005308 /* Possible truncation here in 16-bit environments, but
5309 * real exit codes are just the lower byte in any event.
5310 */
5311 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005312 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005313 /* Indicate failure - this will cause the file object
5314 * to raise an I/O error and translate the last Win32
5315 * error code from errno. We do have a problem with
5316 * last errors that overlap the normal errno table,
5317 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005318 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005319 if (result != EOF) {
5320 /* If the error wasn't from the fclose(), then
5321 * set errno for the file object error handling.
5322 */
5323 errno = GetLastError();
5324 }
5325 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005326 }
5327
5328 /* Free up the native handle at this point */
5329 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005330 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005331
Mark Hammondb37a3732000-08-14 04:47:33 +00005332 /* Remove this file pointer from dictionary */
5333 PyDict_DelItem(_PyPopenProcs, fileObj);
5334
5335 if (PyDict_Size(_PyPopenProcs) == 0) {
5336 Py_DECREF(_PyPopenProcs);
5337 _PyPopenProcs = NULL;
5338 }
5339
5340 } /* if object retrieval ok */
5341
5342 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005343 } /* if _PyPopenProcs */
5344
Tim Peters736aa322000-09-01 06:51:24 +00005345#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005346 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005347#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005348 return result;
5349}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005350
5351#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005353posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005354{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005355 char *name;
5356 char *mode = "r";
5357 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005358 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005359 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005360 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005361 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005362 /* Strip mode of binary or text modifiers */
5363 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5364 mode = "r";
5365 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5366 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005367 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005368 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005369 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005370 if (fp == NULL)
5371 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005372 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005373 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005374 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005375 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005376}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005377
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005378#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005379#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005380
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005381
Guido van Rossumb6775db1994-08-01 11:34:53 +00005382#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005383PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005384"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005385Set the current process's user id.");
5386
Barry Warsaw53699e91996-12-10 23:23:01 +00005387static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005388posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005389{
5390 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005391 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005392 return NULL;
5393 if (setuid(uid) < 0)
5394 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005395 Py_INCREF(Py_None);
5396 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005397}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005398#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005399
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005400
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005401#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005402PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005403"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005404Set the current process's effective user id.");
5405
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005406static PyObject *
5407posix_seteuid (PyObject *self, PyObject *args)
5408{
5409 int euid;
5410 if (!PyArg_ParseTuple(args, "i", &euid)) {
5411 return NULL;
5412 } else if (seteuid(euid) < 0) {
5413 return posix_error();
5414 } else {
5415 Py_INCREF(Py_None);
5416 return Py_None;
5417 }
5418}
5419#endif /* HAVE_SETEUID */
5420
5421#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005422PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005423"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005424Set the current process's effective group id.");
5425
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005426static PyObject *
5427posix_setegid (PyObject *self, PyObject *args)
5428{
5429 int egid;
5430 if (!PyArg_ParseTuple(args, "i", &egid)) {
5431 return NULL;
5432 } else if (setegid(egid) < 0) {
5433 return posix_error();
5434 } else {
5435 Py_INCREF(Py_None);
5436 return Py_None;
5437 }
5438}
5439#endif /* HAVE_SETEGID */
5440
5441#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005442PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005443"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005444Set the current process's real and effective user ids.");
5445
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005446static PyObject *
5447posix_setreuid (PyObject *self, PyObject *args)
5448{
5449 int ruid, euid;
5450 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5451 return NULL;
5452 } else if (setreuid(ruid, euid) < 0) {
5453 return posix_error();
5454 } else {
5455 Py_INCREF(Py_None);
5456 return Py_None;
5457 }
5458}
5459#endif /* HAVE_SETREUID */
5460
5461#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005462PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005463"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005464Set the current process's real and effective group ids.");
5465
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005466static PyObject *
5467posix_setregid (PyObject *self, PyObject *args)
5468{
5469 int rgid, egid;
5470 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5471 return NULL;
5472 } else if (setregid(rgid, egid) < 0) {
5473 return posix_error();
5474 } else {
5475 Py_INCREF(Py_None);
5476 return Py_None;
5477 }
5478}
5479#endif /* HAVE_SETREGID */
5480
Guido van Rossumb6775db1994-08-01 11:34:53 +00005481#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005482PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005483"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005484Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005485
Barry Warsaw53699e91996-12-10 23:23:01 +00005486static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005487posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005488{
5489 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005490 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005491 return NULL;
5492 if (setgid(gid) < 0)
5493 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005494 Py_INCREF(Py_None);
5495 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005496}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005497#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005498
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005499#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005500PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005501"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005502Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005503
5504static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00005505posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005506{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005507 int i, len;
5508 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005509
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005510 if (!PySequence_Check(groups)) {
5511 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5512 return NULL;
5513 }
5514 len = PySequence_Size(groups);
5515 if (len > MAX_GROUPS) {
5516 PyErr_SetString(PyExc_ValueError, "too many groups");
5517 return NULL;
5518 }
5519 for(i = 0; i < len; i++) {
5520 PyObject *elem;
5521 elem = PySequence_GetItem(groups, i);
5522 if (!elem)
5523 return NULL;
Guido van Rossumddefaf32007-01-14 03:31:43 +00005524 if (!PyLong_Check(elem)) {
5525 PyErr_SetString(PyExc_TypeError,
5526 "groups must be integers");
5527 Py_DECREF(elem);
5528 return NULL;
5529 } else {
5530 unsigned long x = PyLong_AsUnsignedLong(elem);
5531 if (PyErr_Occurred()) {
5532 PyErr_SetString(PyExc_TypeError,
5533 "group id too big");
Georg Brandla13c2442005-11-22 19:30:31 +00005534 Py_DECREF(elem);
5535 return NULL;
Georg Brandla13c2442005-11-22 19:30:31 +00005536 }
Georg Brandla13c2442005-11-22 19:30:31 +00005537 grouplist[i] = x;
Guido van Rossumddefaf32007-01-14 03:31:43 +00005538 /* read back the value to see if it fitted in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00005539 if (grouplist[i] != x) {
5540 PyErr_SetString(PyExc_TypeError,
5541 "group id too big");
5542 Py_DECREF(elem);
5543 return NULL;
5544 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005545 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005546 Py_DECREF(elem);
5547 }
5548
5549 if (setgroups(len, grouplist) < 0)
5550 return posix_error();
5551 Py_INCREF(Py_None);
5552 return Py_None;
5553}
5554#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005555
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005556#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
5557static PyObject *
5558wait_helper(int pid, int status, struct rusage *ru)
5559{
5560 PyObject *result;
5561 static PyObject *struct_rusage;
5562
5563 if (pid == -1)
5564 return posix_error();
5565
5566 if (struct_rusage == NULL) {
5567 PyObject *m = PyImport_ImportModule("resource");
5568 if (m == NULL)
5569 return NULL;
5570 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5571 Py_DECREF(m);
5572 if (struct_rusage == NULL)
5573 return NULL;
5574 }
5575
5576 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5577 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5578 if (!result)
5579 return NULL;
5580
5581#ifndef doubletime
5582#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5583#endif
5584
5585 PyStructSequence_SET_ITEM(result, 0,
5586 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5587 PyStructSequence_SET_ITEM(result, 1,
5588 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5589#define SET_INT(result, index, value)\
5590 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5591 SET_INT(result, 2, ru->ru_maxrss);
5592 SET_INT(result, 3, ru->ru_ixrss);
5593 SET_INT(result, 4, ru->ru_idrss);
5594 SET_INT(result, 5, ru->ru_isrss);
5595 SET_INT(result, 6, ru->ru_minflt);
5596 SET_INT(result, 7, ru->ru_majflt);
5597 SET_INT(result, 8, ru->ru_nswap);
5598 SET_INT(result, 9, ru->ru_inblock);
5599 SET_INT(result, 10, ru->ru_oublock);
5600 SET_INT(result, 11, ru->ru_msgsnd);
5601 SET_INT(result, 12, ru->ru_msgrcv);
5602 SET_INT(result, 13, ru->ru_nsignals);
5603 SET_INT(result, 14, ru->ru_nvcsw);
5604 SET_INT(result, 15, ru->ru_nivcsw);
5605#undef SET_INT
5606
5607 if (PyErr_Occurred()) {
5608 Py_DECREF(result);
5609 return NULL;
5610 }
5611
5612 return Py_BuildValue("iiN", pid, status, result);
5613}
5614#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
5615
5616#ifdef HAVE_WAIT3
5617PyDoc_STRVAR(posix_wait3__doc__,
5618"wait3(options) -> (pid, status, rusage)\n\n\
5619Wait for completion of a child process.");
5620
5621static PyObject *
5622posix_wait3(PyObject *self, PyObject *args)
5623{
5624 int pid, options;
5625 struct rusage ru;
5626 WAIT_TYPE status;
5627 WAIT_STATUS_INT(status) = 0;
5628
5629 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5630 return NULL;
5631
5632 Py_BEGIN_ALLOW_THREADS
5633 pid = wait3(&status, options, &ru);
5634 Py_END_ALLOW_THREADS
5635
5636 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5637}
5638#endif /* HAVE_WAIT3 */
5639
5640#ifdef HAVE_WAIT4
5641PyDoc_STRVAR(posix_wait4__doc__,
5642"wait4(pid, options) -> (pid, status, rusage)\n\n\
5643Wait for completion of a given child process.");
5644
5645static PyObject *
5646posix_wait4(PyObject *self, PyObject *args)
5647{
5648 int pid, options;
5649 struct rusage ru;
5650 WAIT_TYPE status;
5651 WAIT_STATUS_INT(status) = 0;
5652
5653 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5654 return NULL;
5655
5656 Py_BEGIN_ALLOW_THREADS
5657 pid = wait4(pid, &status, options, &ru);
5658 Py_END_ALLOW_THREADS
5659
5660 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5661}
5662#endif /* HAVE_WAIT4 */
5663
Guido van Rossumb6775db1994-08-01 11:34:53 +00005664#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005665PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005666"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005667Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005668
Barry Warsaw53699e91996-12-10 23:23:01 +00005669static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005670posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005671{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005672 int pid, options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005673 WAIT_TYPE status;
5674 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005675
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005676 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005677 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005678 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005679 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005680 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005681 if (pid == -1)
5682 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005683
5684 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005685}
5686
Tim Petersab034fa2002-02-01 11:27:43 +00005687#elif defined(HAVE_CWAIT)
5688
5689/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005690PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005691"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005692"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005693
5694static PyObject *
5695posix_waitpid(PyObject *self, PyObject *args)
5696{
Thomas Wouters477c8d52006-05-27 19:21:47 +00005697 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005698 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005699
5700 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5701 return NULL;
5702 Py_BEGIN_ALLOW_THREADS
5703 pid = _cwait(&status, pid, options);
5704 Py_END_ALLOW_THREADS
5705 if (pid == -1)
5706 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005707
5708 /* shift the status left a byte so this is more like the POSIX waitpid */
5709 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005710}
5711#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005712
Guido van Rossumad0ee831995-03-01 10:34:45 +00005713#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005714PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005715"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005716Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005717
Barry Warsaw53699e91996-12-10 23:23:01 +00005718static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005719posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005720{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005721 int pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005722 WAIT_TYPE status;
5723 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005724
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005725 Py_BEGIN_ALLOW_THREADS
5726 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005727 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005728 if (pid == -1)
5729 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005730
5731 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005732}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005733#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005734
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005735
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005736PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005737"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005738Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005739
Barry Warsaw53699e91996-12-10 23:23:01 +00005740static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005741posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005742{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005743#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005744 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005745#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005746#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005747 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005748#else
5749 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5750#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005751#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005752}
5753
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005754
Guido van Rossumb6775db1994-08-01 11:34:53 +00005755#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005756PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005757"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005758Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005759
Barry Warsaw53699e91996-12-10 23:23:01 +00005760static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005761posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005762{
Thomas Wouters89f507f2006-12-13 04:49:30 +00005763 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005764 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005765 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005766 int n;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005767#ifdef Py_USING_UNICODE
5768 int arg_is_unicode = 0;
5769#endif
5770
5771 if (!PyArg_ParseTuple(args, "et:readlink",
5772 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005773 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005774#ifdef Py_USING_UNICODE
5775 v = PySequence_GetItem(args, 0);
5776 if (v == NULL) return NULL;
5777
5778 if (PyUnicode_Check(v)) {
5779 arg_is_unicode = 1;
5780 }
5781 Py_DECREF(v);
5782#endif
5783
Barry Warsaw53699e91996-12-10 23:23:01 +00005784 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005785 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005786 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005787 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005788 return posix_error_with_filename(path);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005789
5790 v = PyString_FromStringAndSize(buf, n);
5791#ifdef Py_USING_UNICODE
5792 if (arg_is_unicode) {
5793 PyObject *w;
5794
5795 w = PyUnicode_FromEncodedObject(v,
5796 Py_FileSystemDefaultEncoding,
5797 "strict");
5798 if (w != NULL) {
5799 Py_DECREF(v);
5800 v = w;
5801 }
5802 else {
5803 /* fall back to the original byte string, as
5804 discussed in patch #683592 */
5805 PyErr_Clear();
5806 }
5807 }
5808#endif
5809 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005810}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005811#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005812
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005813
Guido van Rossumb6775db1994-08-01 11:34:53 +00005814#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005815PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005816"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005817Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005818
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005819static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005820posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005821{
Thomas Wouters477c8d52006-05-27 19:21:47 +00005822 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005823}
5824#endif /* HAVE_SYMLINK */
5825
5826
5827#ifdef HAVE_TIMES
5828#ifndef HZ
5829#define HZ 60 /* Universal constant :-) */
5830#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005831
Guido van Rossumd48f2521997-12-05 22:19:34 +00005832#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5833static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005834system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005835{
5836 ULONG value = 0;
5837
5838 Py_BEGIN_ALLOW_THREADS
5839 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5840 Py_END_ALLOW_THREADS
5841
5842 return value;
5843}
5844
5845static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005846posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005847{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005848 /* Currently Only Uptime is Provided -- Others Later */
5849 return Py_BuildValue("ddddd",
5850 (double)0 /* t.tms_utime / HZ */,
5851 (double)0 /* t.tms_stime / HZ */,
5852 (double)0 /* t.tms_cutime / HZ */,
5853 (double)0 /* t.tms_cstime / HZ */,
5854 (double)system_uptime() / 1000);
5855}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005856#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005857static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005858posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005859{
5860 struct tms t;
5861 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005862 errno = 0;
5863 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005864 if (c == (clock_t) -1)
5865 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005866 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005867 (double)t.tms_utime / HZ,
5868 (double)t.tms_stime / HZ,
5869 (double)t.tms_cutime / HZ,
5870 (double)t.tms_cstime / HZ,
5871 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005872}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005873#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005874#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005875
5876
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005877#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005878#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005879static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005880posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005881{
5882 FILETIME create, exit, kernel, user;
5883 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005884 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005885 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5886 /* The fields of a FILETIME structure are the hi and lo part
5887 of a 64-bit value expressed in 100 nanosecond units.
5888 1e7 is one second in such units; 1e-7 the inverse.
5889 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5890 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005891 return Py_BuildValue(
5892 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005893 (double)(kernel.dwHighDateTime*429.4967296 +
5894 kernel.dwLowDateTime*1e-7),
5895 (double)(user.dwHighDateTime*429.4967296 +
5896 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005897 (double)0,
5898 (double)0,
5899 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005900}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005901#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005902
5903#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005904PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005905"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005906Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005907#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005908
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005909
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005910#ifdef HAVE_GETSID
5911PyDoc_STRVAR(posix_getsid__doc__,
5912"getsid(pid) -> sid\n\n\
5913Call the system call getsid().");
5914
5915static PyObject *
5916posix_getsid(PyObject *self, PyObject *args)
5917{
5918 int pid, sid;
5919 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5920 return NULL;
5921 sid = getsid(pid);
5922 if (sid < 0)
5923 return posix_error();
5924 return PyInt_FromLong((long)sid);
5925}
5926#endif /* HAVE_GETSID */
5927
5928
Guido van Rossumb6775db1994-08-01 11:34:53 +00005929#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005930PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005931"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005932Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005933
Barry Warsaw53699e91996-12-10 23:23:01 +00005934static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005935posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005936{
Guido van Rossum687dd131993-05-17 08:34:16 +00005937 if (setsid() < 0)
5938 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005939 Py_INCREF(Py_None);
5940 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005941}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005942#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005943
Guido van Rossumb6775db1994-08-01 11:34:53 +00005944#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005945PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005946"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005947Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005948
Barry Warsaw53699e91996-12-10 23:23:01 +00005949static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005950posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005951{
5952 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005953 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005954 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005955 if (setpgid(pid, pgrp) < 0)
5956 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005957 Py_INCREF(Py_None);
5958 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005959}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005960#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005961
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005962
Guido van Rossumb6775db1994-08-01 11:34:53 +00005963#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005964PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005965"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005966Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005967
Barry Warsaw53699e91996-12-10 23:23:01 +00005968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005969posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005970{
5971 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005972 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005973 return NULL;
5974 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005975 if (pgid < 0)
5976 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005977 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005978}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005979#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005980
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005981
Guido van Rossumb6775db1994-08-01 11:34:53 +00005982#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005983PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005984"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005985Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005986
Barry Warsaw53699e91996-12-10 23:23:01 +00005987static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005988posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005989{
5990 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005991 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005992 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005993 if (tcsetpgrp(fd, pgid) < 0)
5994 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005995 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005996 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005997}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005998#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005999
Guido van Rossum687dd131993-05-17 08:34:16 +00006000/* Functions acting on file descriptors */
6001
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006002PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006003"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006004Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006005
Barry Warsaw53699e91996-12-10 23:23:01 +00006006static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006007posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006008{
Mark Hammondef8b6542001-05-13 08:04:26 +00006009 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006010 int flag;
6011 int mode = 0777;
6012 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006013
6014#ifdef MS_WINDOWS
6015 if (unicode_file_names()) {
6016 PyUnicodeObject *po;
6017 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6018 Py_BEGIN_ALLOW_THREADS
6019 /* PyUnicode_AS_UNICODE OK without thread
6020 lock as it is a simple dereference. */
6021 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6022 Py_END_ALLOW_THREADS
6023 if (fd < 0)
6024 return posix_error();
6025 return PyInt_FromLong((long)fd);
6026 }
6027 /* Drop the argument parsing error as narrow strings
6028 are also valid. */
6029 PyErr_Clear();
6030 }
6031#endif
6032
Tim Peters5aa91602002-01-30 05:46:57 +00006033 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006034 Py_FileSystemDefaultEncoding, &file,
6035 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006036 return NULL;
6037
Barry Warsaw53699e91996-12-10 23:23:01 +00006038 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006039 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006040 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006041 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006042 return posix_error_with_allocated_filename(file);
6043 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006044 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006045}
6046
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006047
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006048PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006049"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006050Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006051
Barry Warsaw53699e91996-12-10 23:23:01 +00006052static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006053posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006054{
6055 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006056 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006057 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006058 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006059 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006060 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006061 if (res < 0)
6062 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006063 Py_INCREF(Py_None);
6064 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006065}
6066
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006067
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006068PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006069"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006070Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006071
Barry Warsaw53699e91996-12-10 23:23:01 +00006072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006073posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006074{
6075 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006076 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006077 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006078 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006079 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006080 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006081 if (fd < 0)
6082 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006083 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006084}
6085
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006086
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006087PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006088"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006089Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006090
Barry Warsaw53699e91996-12-10 23:23:01 +00006091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006092posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006093{
6094 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006095 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006096 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006097 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006098 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006099 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006100 if (res < 0)
6101 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006102 Py_INCREF(Py_None);
6103 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006104}
6105
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006106
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006107PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006108"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006109Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006110
Barry Warsaw53699e91996-12-10 23:23:01 +00006111static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006112posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006113{
6114 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006115#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006116 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006117#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006118 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006119#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006120 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006121 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006122 return NULL;
6123#ifdef SEEK_SET
6124 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6125 switch (how) {
6126 case 0: how = SEEK_SET; break;
6127 case 1: how = SEEK_CUR; break;
6128 case 2: how = SEEK_END; break;
6129 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006130#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006131
6132#if !defined(HAVE_LARGEFILE_SUPPORT)
6133 pos = PyInt_AsLong(posobj);
6134#else
6135 pos = PyLong_Check(posobj) ?
6136 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6137#endif
6138 if (PyErr_Occurred())
6139 return NULL;
6140
Barry Warsaw53699e91996-12-10 23:23:01 +00006141 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006142#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006143 res = _lseeki64(fd, pos, how);
6144#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006145 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006146#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006147 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006148 if (res < 0)
6149 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006150
6151#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006152 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006153#else
6154 return PyLong_FromLongLong(res);
6155#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006156}
6157
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006158
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006159PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006160"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006161Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006162
Barry Warsaw53699e91996-12-10 23:23:01 +00006163static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006164posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006165{
Guido van Rossum8bac5461996-06-11 18:38:48 +00006166 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006167 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006168 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006169 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006170 if (size < 0) {
6171 errno = EINVAL;
6172 return posix_error();
6173 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006174 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006175 if (buffer == NULL)
6176 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006177 Py_BEGIN_ALLOW_THREADS
6178 n = read(fd, PyString_AsString(buffer), size);
6179 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006180 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006181 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006182 return posix_error();
6183 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006184 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00006185 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006186 return buffer;
6187}
6188
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006189
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006190PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006191"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006192Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006193
Barry Warsaw53699e91996-12-10 23:23:01 +00006194static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006195posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006196{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006197 int fd;
6198 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00006199 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006200
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006201 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006202 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006203 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006204 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006205 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006206 if (size < 0)
6207 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006208 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006209}
6210
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006211
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006212PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006213"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006214Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006215
Barry Warsaw53699e91996-12-10 23:23:01 +00006216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006217posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006218{
6219 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006220 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006221 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006222 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006223 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006224#ifdef __VMS
6225 /* on OpenVMS we must ensure that all bytes are written to the file */
6226 fsync(fd);
6227#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006228 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006229 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006230 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006231 if (res != 0) {
6232#ifdef MS_WINDOWS
6233 return win32_error("fstat", NULL);
6234#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006235 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006236#endif
6237 }
Tim Peters5aa91602002-01-30 05:46:57 +00006238
Martin v. Löwis14694662006-02-03 12:54:16 +00006239 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006240}
6241
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006242
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006243PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006244"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006245Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006246
Barry Warsaw53699e91996-12-10 23:23:01 +00006247static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006248posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006249{
Guido van Rossum687dd131993-05-17 08:34:16 +00006250 int fd;
Guido van Rossumd8faa362007-04-27 19:54:29 +00006251 char *orgmode = "r";
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006252 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006253 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006254 PyObject *f;
Guido van Rossumd8faa362007-04-27 19:54:29 +00006255 char *mode;
6256 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006257 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006258
Guido van Rossumd8faa362007-04-27 19:54:29 +00006259 /* Sanitize mode. See fileobject.c */
6260 mode = PyMem_MALLOC(strlen(orgmode)+3);
6261 if (!mode) {
6262 PyErr_NoMemory();
6263 return NULL;
6264 }
6265 strcpy(mode, orgmode);
6266 if (_PyFile_SanitizeMode(mode)) {
6267 PyMem_FREE(mode);
Thomas Heller1f043e22002-11-07 16:00:59 +00006268 return NULL;
6269 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006270 Py_BEGIN_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006271#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
6272 if (mode[0] == 'a') {
6273 /* try to make sure the O_APPEND flag is set */
6274 int flags;
6275 flags = fcntl(fd, F_GETFL);
6276 if (flags != -1)
6277 fcntl(fd, F_SETFL, flags | O_APPEND);
6278 fp = fdopen(fd, mode);
6279 if (fp == NULL && flags != -1)
6280 /* restore old mode if fdopen failed */
6281 fcntl(fd, F_SETFL, flags);
6282 } else {
6283 fp = fdopen(fd, mode);
6284 }
6285#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006286 fp = fdopen(fd, mode);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006287#endif
Guido van Rossumd8faa362007-04-27 19:54:29 +00006288 PyMem_FREE(mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006289 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006290 if (fp == NULL)
6291 return posix_error();
Guido van Rossumd8faa362007-04-27 19:54:29 +00006292 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006293 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006294 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006295 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006296}
6297
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006298PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006299"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006300Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006301connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006302
6303static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006304posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006305{
6306 int fd;
6307 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6308 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006309 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006310}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006311
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006312#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006313PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006314"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006315Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006316
Barry Warsaw53699e91996-12-10 23:23:01 +00006317static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006318posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006319{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006320#if defined(PYOS_OS2)
6321 HFILE read, write;
6322 APIRET rc;
6323
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006324 Py_BEGIN_ALLOW_THREADS
6325 rc = DosCreatePipe( &read, &write, 4096);
6326 Py_END_ALLOW_THREADS
6327 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006328 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006329
6330 return Py_BuildValue("(ii)", read, write);
6331#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006332#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006333 int fds[2];
6334 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006335 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006336 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006337 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006338 if (res != 0)
6339 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006340 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006341#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006342 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006343 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006344 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006345 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006346 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006347 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006348 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006349 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006350 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6351 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006352 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006353#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006354#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006355}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006356#endif /* HAVE_PIPE */
6357
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006358
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006359#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006360PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006361"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006362Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006363
Barry Warsaw53699e91996-12-10 23:23:01 +00006364static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006365posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006366{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006367 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006368 int mode = 0666;
6369 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006370 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006371 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006372 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006373 res = mkfifo(filename, mode);
6374 Py_END_ALLOW_THREADS
6375 if (res < 0)
6376 return posix_error();
6377 Py_INCREF(Py_None);
6378 return Py_None;
6379}
6380#endif
6381
6382
Neal Norwitz11690112002-07-30 01:08:28 +00006383#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006384PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006385"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006386Create a filesystem node (file, device special file or named pipe)\n\
6387named filename. mode specifies both the permissions to use and the\n\
6388type of node to be created, being combined (bitwise OR) with one of\n\
6389S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006390device defines the newly created device special file (probably using\n\
6391os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006392
6393
6394static PyObject *
6395posix_mknod(PyObject *self, PyObject *args)
6396{
6397 char *filename;
6398 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006399 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006400 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006401 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006402 return NULL;
6403 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006404 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006405 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006406 if (res < 0)
6407 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006408 Py_INCREF(Py_None);
6409 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006410}
6411#endif
6412
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006413#ifdef HAVE_DEVICE_MACROS
6414PyDoc_STRVAR(posix_major__doc__,
6415"major(device) -> major number\n\
6416Extracts a device major number from a raw device number.");
6417
6418static PyObject *
6419posix_major(PyObject *self, PyObject *args)
6420{
6421 int device;
6422 if (!PyArg_ParseTuple(args, "i:major", &device))
6423 return NULL;
6424 return PyInt_FromLong((long)major(device));
6425}
6426
6427PyDoc_STRVAR(posix_minor__doc__,
6428"minor(device) -> minor number\n\
6429Extracts a device minor number from a raw device number.");
6430
6431static PyObject *
6432posix_minor(PyObject *self, PyObject *args)
6433{
6434 int device;
6435 if (!PyArg_ParseTuple(args, "i:minor", &device))
6436 return NULL;
6437 return PyInt_FromLong((long)minor(device));
6438}
6439
6440PyDoc_STRVAR(posix_makedev__doc__,
6441"makedev(major, minor) -> device number\n\
6442Composes a raw device number from the major and minor device numbers.");
6443
6444static PyObject *
6445posix_makedev(PyObject *self, PyObject *args)
6446{
6447 int major, minor;
6448 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6449 return NULL;
6450 return PyInt_FromLong((long)makedev(major, minor));
6451}
6452#endif /* device macros */
6453
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006454
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006455#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006456PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006457"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006458Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006459
Barry Warsaw53699e91996-12-10 23:23:01 +00006460static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006461posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006462{
6463 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006464 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006465 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006466 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006467
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006468 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006469 return NULL;
6470
6471#if !defined(HAVE_LARGEFILE_SUPPORT)
6472 length = PyInt_AsLong(lenobj);
6473#else
6474 length = PyLong_Check(lenobj) ?
6475 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6476#endif
6477 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006478 return NULL;
6479
Barry Warsaw53699e91996-12-10 23:23:01 +00006480 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006481 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006482 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006483 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006484 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006485 return NULL;
6486 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006487 Py_INCREF(Py_None);
6488 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006489}
6490#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006491
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006492#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006493PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006494"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006495Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006496
Fred Drake762e2061999-08-26 17:23:54 +00006497/* Save putenv() parameters as values here, so we can collect them when they
6498 * get re-set with another call for the same key. */
6499static PyObject *posix_putenv_garbage;
6500
Tim Peters5aa91602002-01-30 05:46:57 +00006501static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006502posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006503{
6504 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006505 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006506 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006507 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006508
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006509 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006510 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006511
6512#if defined(PYOS_OS2)
6513 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6514 APIRET rc;
6515
Guido van Rossumd48f2521997-12-05 22:19:34 +00006516 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6517 if (rc != NO_ERROR)
6518 return os2_error(rc);
6519
6520 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6521 APIRET rc;
6522
Guido van Rossumd48f2521997-12-05 22:19:34 +00006523 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6524 if (rc != NO_ERROR)
6525 return os2_error(rc);
6526 } else {
6527#endif
6528
Fred Drake762e2061999-08-26 17:23:54 +00006529 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006530 len = strlen(s1) + strlen(s2) + 2;
6531 /* len includes space for a trailing \0; the size arg to
6532 PyString_FromStringAndSize does not count that */
6533 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006534 if (newstr == NULL)
6535 return PyErr_NoMemory();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006536 newenv = PyString_AS_STRING(newstr);
6537 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6538 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006539 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006540 posix_error();
6541 return NULL;
6542 }
Fred Drake762e2061999-08-26 17:23:54 +00006543 /* Install the first arg and newstr in posix_putenv_garbage;
6544 * this will cause previous value to be collected. This has to
6545 * happen after the real putenv() call because the old value
6546 * was still accessible until then. */
6547 if (PyDict_SetItem(posix_putenv_garbage,
6548 PyTuple_GET_ITEM(args, 0), newstr)) {
6549 /* really not much we can do; just leak */
6550 PyErr_Clear();
6551 }
6552 else {
6553 Py_DECREF(newstr);
6554 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006555
6556#if defined(PYOS_OS2)
6557 }
6558#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006559 Py_INCREF(Py_None);
6560 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006561}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006562#endif /* putenv */
6563
Guido van Rossumc524d952001-10-19 01:31:59 +00006564#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006565PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006566"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006567Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006568
6569static PyObject *
6570posix_unsetenv(PyObject *self, PyObject *args)
6571{
6572 char *s1;
6573
6574 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6575 return NULL;
6576
6577 unsetenv(s1);
6578
6579 /* Remove the key from posix_putenv_garbage;
6580 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006581 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006582 * old value was still accessible until then.
6583 */
6584 if (PyDict_DelItem(posix_putenv_garbage,
6585 PyTuple_GET_ITEM(args, 0))) {
6586 /* really not much we can do; just leak */
6587 PyErr_Clear();
6588 }
6589
6590 Py_INCREF(Py_None);
6591 return Py_None;
6592}
6593#endif /* unsetenv */
6594
Guido van Rossumb6a47161997-09-15 22:54:34 +00006595#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006596PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006597"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006598Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006599
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006600static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006601posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006602{
6603 int code;
6604 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006605 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006606 return NULL;
6607 message = strerror(code);
6608 if (message == NULL) {
6609 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006610 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006611 return NULL;
6612 }
6613 return PyString_FromString(message);
6614}
6615#endif /* strerror */
6616
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006617
Guido van Rossumc9641791998-08-04 15:26:23 +00006618#ifdef HAVE_SYS_WAIT_H
6619
Fred Drake106c1a02002-04-23 15:58:02 +00006620#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006621PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006622"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006623Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006624
6625static PyObject *
6626posix_WCOREDUMP(PyObject *self, PyObject *args)
6627{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006628 WAIT_TYPE status;
6629 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006630
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006631 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006632 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006633
6634 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006635}
6636#endif /* WCOREDUMP */
6637
6638#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006639PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006640"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006641Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006642job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006643
6644static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006645posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006646{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006647 WAIT_TYPE status;
6648 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006649
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006650 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006651 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006652
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006653 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006654}
6655#endif /* WIFCONTINUED */
6656
Guido van Rossumc9641791998-08-04 15:26:23 +00006657#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006658PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006659"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006660Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006661
6662static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006663posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006664{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006665 WAIT_TYPE status;
6666 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006667
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006668 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006669 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006670
Fred Drake106c1a02002-04-23 15:58:02 +00006671 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006672}
6673#endif /* WIFSTOPPED */
6674
6675#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006676PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006677"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006678Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006679
6680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006681posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006682{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006683 WAIT_TYPE status;
6684 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006685
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006686 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006687 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006688
Fred Drake106c1a02002-04-23 15:58:02 +00006689 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006690}
6691#endif /* WIFSIGNALED */
6692
6693#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006694PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006695"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006696Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006697system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006698
6699static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006700posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006701{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006702 WAIT_TYPE status;
6703 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006704
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006705 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006706 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006707
Fred Drake106c1a02002-04-23 15:58:02 +00006708 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006709}
6710#endif /* WIFEXITED */
6711
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006712#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006713PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006714"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006715Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006716
6717static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006718posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006719{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006720 WAIT_TYPE status;
6721 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006722
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006723 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006724 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006725
Guido van Rossumc9641791998-08-04 15:26:23 +00006726 return Py_BuildValue("i", WEXITSTATUS(status));
6727}
6728#endif /* WEXITSTATUS */
6729
6730#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006731PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006732"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006733Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006734value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006735
6736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006737posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006738{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006739 WAIT_TYPE status;
6740 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006741
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006742 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006743 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006744
Guido van Rossumc9641791998-08-04 15:26:23 +00006745 return Py_BuildValue("i", WTERMSIG(status));
6746}
6747#endif /* WTERMSIG */
6748
6749#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006750PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006751"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006752Return the signal that stopped the process that provided\n\
6753the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006754
6755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006756posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006757{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006758 WAIT_TYPE status;
6759 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006760
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006761 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006762 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006763
Guido van Rossumc9641791998-08-04 15:26:23 +00006764 return Py_BuildValue("i", WSTOPSIG(status));
6765}
6766#endif /* WSTOPSIG */
6767
6768#endif /* HAVE_SYS_WAIT_H */
6769
6770
Thomas Wouters477c8d52006-05-27 19:21:47 +00006771#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006772#ifdef _SCO_DS
6773/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6774 needed definitions in sys/statvfs.h */
6775#define _SVID3
6776#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006777#include <sys/statvfs.h>
6778
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006779static PyObject*
6780_pystatvfs_fromstructstatvfs(struct statvfs st) {
6781 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6782 if (v == NULL)
6783 return NULL;
6784
6785#if !defined(HAVE_LARGEFILE_SUPPORT)
6786 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6787 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6788 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6789 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6790 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6791 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6792 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6793 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6794 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6795 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6796#else
6797 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6798 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006799 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006800 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006801 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006802 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006803 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006804 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006805 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006806 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006807 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006808 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006809 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006810 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006811 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6812 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6813#endif
6814
6815 return v;
6816}
6817
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006818PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006819"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006820Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006821
6822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006823posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006824{
6825 int fd, res;
6826 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006827
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006828 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006829 return NULL;
6830 Py_BEGIN_ALLOW_THREADS
6831 res = fstatvfs(fd, &st);
6832 Py_END_ALLOW_THREADS
6833 if (res != 0)
6834 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006835
6836 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006837}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006838#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006839
6840
Thomas Wouters477c8d52006-05-27 19:21:47 +00006841#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006842#include <sys/statvfs.h>
6843
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006844PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006845"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006846Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006847
6848static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006849posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006850{
6851 char *path;
6852 int res;
6853 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006854 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006855 return NULL;
6856 Py_BEGIN_ALLOW_THREADS
6857 res = statvfs(path, &st);
6858 Py_END_ALLOW_THREADS
6859 if (res != 0)
6860 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006861
6862 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006863}
6864#endif /* HAVE_STATVFS */
6865
6866
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006867#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006868PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006869"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006870Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006871The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006872or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006873
6874static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006875posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006876{
6877 PyObject *result = NULL;
6878 char *dir = NULL;
6879 char *pfx = NULL;
6880 char *name;
6881
6882 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6883 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006884
6885 if (PyErr_Warn(PyExc_RuntimeWarning,
6886 "tempnam is a potential security risk to your program") < 0)
6887 return NULL;
6888
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006889#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006890 name = _tempnam(dir, pfx);
6891#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006892 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006893#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006894 if (name == NULL)
6895 return PyErr_NoMemory();
6896 result = PyString_FromString(name);
6897 free(name);
6898 return result;
6899}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006900#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006901
6902
6903#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006904PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006905"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006906Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006907
6908static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006909posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006910{
6911 FILE *fp;
6912
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006913 fp = tmpfile();
6914 if (fp == NULL)
6915 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006916 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006917}
6918#endif
6919
6920
6921#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006922PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006923"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006924Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006925
6926static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006927posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006928{
6929 char buffer[L_tmpnam];
6930 char *name;
6931
Skip Montanaro95618b52001-08-18 18:52:10 +00006932 if (PyErr_Warn(PyExc_RuntimeWarning,
6933 "tmpnam is a potential security risk to your program") < 0)
6934 return NULL;
6935
Greg Wardb48bc172000-03-01 21:51:56 +00006936#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006937 name = tmpnam_r(buffer);
6938#else
6939 name = tmpnam(buffer);
6940#endif
6941 if (name == NULL) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006942 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006943#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006944 "unexpected NULL from tmpnam_r"
6945#else
6946 "unexpected NULL from tmpnam"
6947#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006948 );
6949 PyErr_SetObject(PyExc_OSError, err);
6950 Py_XDECREF(err);
6951 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006952 }
6953 return PyString_FromString(buffer);
6954}
6955#endif
6956
6957
Fred Drakec9680921999-12-13 16:37:25 +00006958/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6959 * It maps strings representing configuration variable names to
6960 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006961 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006962 * rarely-used constants. There are three separate tables that use
6963 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006964 *
6965 * This code is always included, even if none of the interfaces that
6966 * need it are included. The #if hackery needed to avoid it would be
6967 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006968 */
6969struct constdef {
6970 char *name;
6971 long value;
6972};
6973
Fred Drake12c6e2d1999-12-14 21:25:03 +00006974static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006975conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6976 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006977{
6978 if (PyInt_Check(arg)) {
6979 *valuep = PyInt_AS_LONG(arg);
6980 return 1;
6981 }
6982 if (PyString_Check(arg)) {
6983 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006984 size_t lo = 0;
6985 size_t mid;
6986 size_t hi = tablesize;
6987 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006988 char *confname = PyString_AS_STRING(arg);
6989 while (lo < hi) {
6990 mid = (lo + hi) / 2;
6991 cmp = strcmp(confname, table[mid].name);
6992 if (cmp < 0)
6993 hi = mid;
6994 else if (cmp > 0)
6995 lo = mid + 1;
6996 else {
6997 *valuep = table[mid].value;
6998 return 1;
6999 }
7000 }
7001 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7002 }
7003 else
7004 PyErr_SetString(PyExc_TypeError,
7005 "configuration names must be strings or integers");
7006 return 0;
7007}
7008
7009
7010#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7011static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007012#ifdef _PC_ABI_AIO_XFER_MAX
7013 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7014#endif
7015#ifdef _PC_ABI_ASYNC_IO
7016 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7017#endif
Fred Drakec9680921999-12-13 16:37:25 +00007018#ifdef _PC_ASYNC_IO
7019 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7020#endif
7021#ifdef _PC_CHOWN_RESTRICTED
7022 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7023#endif
7024#ifdef _PC_FILESIZEBITS
7025 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7026#endif
7027#ifdef _PC_LAST
7028 {"PC_LAST", _PC_LAST},
7029#endif
7030#ifdef _PC_LINK_MAX
7031 {"PC_LINK_MAX", _PC_LINK_MAX},
7032#endif
7033#ifdef _PC_MAX_CANON
7034 {"PC_MAX_CANON", _PC_MAX_CANON},
7035#endif
7036#ifdef _PC_MAX_INPUT
7037 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7038#endif
7039#ifdef _PC_NAME_MAX
7040 {"PC_NAME_MAX", _PC_NAME_MAX},
7041#endif
7042#ifdef _PC_NO_TRUNC
7043 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7044#endif
7045#ifdef _PC_PATH_MAX
7046 {"PC_PATH_MAX", _PC_PATH_MAX},
7047#endif
7048#ifdef _PC_PIPE_BUF
7049 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7050#endif
7051#ifdef _PC_PRIO_IO
7052 {"PC_PRIO_IO", _PC_PRIO_IO},
7053#endif
7054#ifdef _PC_SOCK_MAXBUF
7055 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7056#endif
7057#ifdef _PC_SYNC_IO
7058 {"PC_SYNC_IO", _PC_SYNC_IO},
7059#endif
7060#ifdef _PC_VDISABLE
7061 {"PC_VDISABLE", _PC_VDISABLE},
7062#endif
7063};
7064
Fred Drakec9680921999-12-13 16:37:25 +00007065static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007066conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007067{
7068 return conv_confname(arg, valuep, posix_constants_pathconf,
7069 sizeof(posix_constants_pathconf)
7070 / sizeof(struct constdef));
7071}
7072#endif
7073
7074#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007075PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007076"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007077Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007078If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007079
7080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007081posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007082{
7083 PyObject *result = NULL;
7084 int name, fd;
7085
Fred Drake12c6e2d1999-12-14 21:25:03 +00007086 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7087 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00007088 long limit;
7089
7090 errno = 0;
7091 limit = fpathconf(fd, name);
7092 if (limit == -1 && errno != 0)
7093 posix_error();
7094 else
7095 result = PyInt_FromLong(limit);
7096 }
7097 return result;
7098}
7099#endif
7100
7101
7102#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007103PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007104"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007105Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007106If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007107
7108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007109posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007110{
7111 PyObject *result = NULL;
7112 int name;
7113 char *path;
7114
7115 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7116 conv_path_confname, &name)) {
7117 long limit;
7118
7119 errno = 0;
7120 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007121 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00007122 if (errno == EINVAL)
7123 /* could be a path or name problem */
7124 posix_error();
7125 else
7126 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007127 }
Fred Drakec9680921999-12-13 16:37:25 +00007128 else
7129 result = PyInt_FromLong(limit);
7130 }
7131 return result;
7132}
7133#endif
7134
7135#ifdef HAVE_CONFSTR
7136static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007137#ifdef _CS_ARCHITECTURE
7138 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7139#endif
7140#ifdef _CS_HOSTNAME
7141 {"CS_HOSTNAME", _CS_HOSTNAME},
7142#endif
7143#ifdef _CS_HW_PROVIDER
7144 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7145#endif
7146#ifdef _CS_HW_SERIAL
7147 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7148#endif
7149#ifdef _CS_INITTAB_NAME
7150 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7151#endif
Fred Drakec9680921999-12-13 16:37:25 +00007152#ifdef _CS_LFS64_CFLAGS
7153 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7154#endif
7155#ifdef _CS_LFS64_LDFLAGS
7156 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7157#endif
7158#ifdef _CS_LFS64_LIBS
7159 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7160#endif
7161#ifdef _CS_LFS64_LINTFLAGS
7162 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7163#endif
7164#ifdef _CS_LFS_CFLAGS
7165 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7166#endif
7167#ifdef _CS_LFS_LDFLAGS
7168 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7169#endif
7170#ifdef _CS_LFS_LIBS
7171 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7172#endif
7173#ifdef _CS_LFS_LINTFLAGS
7174 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7175#endif
Fred Draked86ed291999-12-15 15:34:33 +00007176#ifdef _CS_MACHINE
7177 {"CS_MACHINE", _CS_MACHINE},
7178#endif
Fred Drakec9680921999-12-13 16:37:25 +00007179#ifdef _CS_PATH
7180 {"CS_PATH", _CS_PATH},
7181#endif
Fred Draked86ed291999-12-15 15:34:33 +00007182#ifdef _CS_RELEASE
7183 {"CS_RELEASE", _CS_RELEASE},
7184#endif
7185#ifdef _CS_SRPC_DOMAIN
7186 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7187#endif
7188#ifdef _CS_SYSNAME
7189 {"CS_SYSNAME", _CS_SYSNAME},
7190#endif
7191#ifdef _CS_VERSION
7192 {"CS_VERSION", _CS_VERSION},
7193#endif
Fred Drakec9680921999-12-13 16:37:25 +00007194#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7195 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7196#endif
7197#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7198 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7199#endif
7200#ifdef _CS_XBS5_ILP32_OFF32_LIBS
7201 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7202#endif
7203#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7204 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7205#endif
7206#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7207 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7208#endif
7209#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7210 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7211#endif
7212#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7213 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7214#endif
7215#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7216 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7217#endif
7218#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7219 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7220#endif
7221#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7222 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7223#endif
7224#ifdef _CS_XBS5_LP64_OFF64_LIBS
7225 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7226#endif
7227#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7228 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7229#endif
7230#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7231 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7232#endif
7233#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7234 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7235#endif
7236#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7237 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7238#endif
7239#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7240 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7241#endif
Fred Draked86ed291999-12-15 15:34:33 +00007242#ifdef _MIPS_CS_AVAIL_PROCESSORS
7243 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7244#endif
7245#ifdef _MIPS_CS_BASE
7246 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7247#endif
7248#ifdef _MIPS_CS_HOSTID
7249 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7250#endif
7251#ifdef _MIPS_CS_HW_NAME
7252 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7253#endif
7254#ifdef _MIPS_CS_NUM_PROCESSORS
7255 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7256#endif
7257#ifdef _MIPS_CS_OSREL_MAJ
7258 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7259#endif
7260#ifdef _MIPS_CS_OSREL_MIN
7261 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7262#endif
7263#ifdef _MIPS_CS_OSREL_PATCH
7264 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7265#endif
7266#ifdef _MIPS_CS_OS_NAME
7267 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7268#endif
7269#ifdef _MIPS_CS_OS_PROVIDER
7270 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7271#endif
7272#ifdef _MIPS_CS_PROCESSORS
7273 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7274#endif
7275#ifdef _MIPS_CS_SERIAL
7276 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7277#endif
7278#ifdef _MIPS_CS_VENDOR
7279 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7280#endif
Fred Drakec9680921999-12-13 16:37:25 +00007281};
7282
7283static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007284conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007285{
7286 return conv_confname(arg, valuep, posix_constants_confstr,
7287 sizeof(posix_constants_confstr)
7288 / sizeof(struct constdef));
7289}
7290
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007291PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007292"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007293Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007294
7295static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007296posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007297{
7298 PyObject *result = NULL;
7299 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007300 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007301
7302 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007303 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007304
Fred Drakec9680921999-12-13 16:37:25 +00007305 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007306 len = confstr(name, buffer, sizeof(buffer));
7307 if (len == 0) {
7308 if (errno) {
7309 posix_error();
7310 }
7311 else {
7312 result = Py_None;
7313 Py_INCREF(Py_None);
7314 }
Fred Drakec9680921999-12-13 16:37:25 +00007315 }
7316 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007317 if ((unsigned int)len >= sizeof(buffer)) {
7318 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007319 if (result != NULL)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007320 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007321 }
7322 else
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007323 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007324 }
7325 }
7326 return result;
7327}
7328#endif
7329
7330
7331#ifdef HAVE_SYSCONF
7332static struct constdef posix_constants_sysconf[] = {
7333#ifdef _SC_2_CHAR_TERM
7334 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7335#endif
7336#ifdef _SC_2_C_BIND
7337 {"SC_2_C_BIND", _SC_2_C_BIND},
7338#endif
7339#ifdef _SC_2_C_DEV
7340 {"SC_2_C_DEV", _SC_2_C_DEV},
7341#endif
7342#ifdef _SC_2_C_VERSION
7343 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7344#endif
7345#ifdef _SC_2_FORT_DEV
7346 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7347#endif
7348#ifdef _SC_2_FORT_RUN
7349 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7350#endif
7351#ifdef _SC_2_LOCALEDEF
7352 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7353#endif
7354#ifdef _SC_2_SW_DEV
7355 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7356#endif
7357#ifdef _SC_2_UPE
7358 {"SC_2_UPE", _SC_2_UPE},
7359#endif
7360#ifdef _SC_2_VERSION
7361 {"SC_2_VERSION", _SC_2_VERSION},
7362#endif
Fred Draked86ed291999-12-15 15:34:33 +00007363#ifdef _SC_ABI_ASYNCHRONOUS_IO
7364 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7365#endif
7366#ifdef _SC_ACL
7367 {"SC_ACL", _SC_ACL},
7368#endif
Fred Drakec9680921999-12-13 16:37:25 +00007369#ifdef _SC_AIO_LISTIO_MAX
7370 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7371#endif
Fred Drakec9680921999-12-13 16:37:25 +00007372#ifdef _SC_AIO_MAX
7373 {"SC_AIO_MAX", _SC_AIO_MAX},
7374#endif
7375#ifdef _SC_AIO_PRIO_DELTA_MAX
7376 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7377#endif
7378#ifdef _SC_ARG_MAX
7379 {"SC_ARG_MAX", _SC_ARG_MAX},
7380#endif
7381#ifdef _SC_ASYNCHRONOUS_IO
7382 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7383#endif
7384#ifdef _SC_ATEXIT_MAX
7385 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7386#endif
Fred Draked86ed291999-12-15 15:34:33 +00007387#ifdef _SC_AUDIT
7388 {"SC_AUDIT", _SC_AUDIT},
7389#endif
Fred Drakec9680921999-12-13 16:37:25 +00007390#ifdef _SC_AVPHYS_PAGES
7391 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7392#endif
7393#ifdef _SC_BC_BASE_MAX
7394 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7395#endif
7396#ifdef _SC_BC_DIM_MAX
7397 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7398#endif
7399#ifdef _SC_BC_SCALE_MAX
7400 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7401#endif
7402#ifdef _SC_BC_STRING_MAX
7403 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7404#endif
Fred Draked86ed291999-12-15 15:34:33 +00007405#ifdef _SC_CAP
7406 {"SC_CAP", _SC_CAP},
7407#endif
Fred Drakec9680921999-12-13 16:37:25 +00007408#ifdef _SC_CHARCLASS_NAME_MAX
7409 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7410#endif
7411#ifdef _SC_CHAR_BIT
7412 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7413#endif
7414#ifdef _SC_CHAR_MAX
7415 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7416#endif
7417#ifdef _SC_CHAR_MIN
7418 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7419#endif
7420#ifdef _SC_CHILD_MAX
7421 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7422#endif
7423#ifdef _SC_CLK_TCK
7424 {"SC_CLK_TCK", _SC_CLK_TCK},
7425#endif
7426#ifdef _SC_COHER_BLKSZ
7427 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7428#endif
7429#ifdef _SC_COLL_WEIGHTS_MAX
7430 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7431#endif
7432#ifdef _SC_DCACHE_ASSOC
7433 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7434#endif
7435#ifdef _SC_DCACHE_BLKSZ
7436 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7437#endif
7438#ifdef _SC_DCACHE_LINESZ
7439 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7440#endif
7441#ifdef _SC_DCACHE_SZ
7442 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7443#endif
7444#ifdef _SC_DCACHE_TBLKSZ
7445 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7446#endif
7447#ifdef _SC_DELAYTIMER_MAX
7448 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7449#endif
7450#ifdef _SC_EQUIV_CLASS_MAX
7451 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7452#endif
7453#ifdef _SC_EXPR_NEST_MAX
7454 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7455#endif
7456#ifdef _SC_FSYNC
7457 {"SC_FSYNC", _SC_FSYNC},
7458#endif
7459#ifdef _SC_GETGR_R_SIZE_MAX
7460 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7461#endif
7462#ifdef _SC_GETPW_R_SIZE_MAX
7463 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7464#endif
7465#ifdef _SC_ICACHE_ASSOC
7466 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7467#endif
7468#ifdef _SC_ICACHE_BLKSZ
7469 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7470#endif
7471#ifdef _SC_ICACHE_LINESZ
7472 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7473#endif
7474#ifdef _SC_ICACHE_SZ
7475 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7476#endif
Fred Draked86ed291999-12-15 15:34:33 +00007477#ifdef _SC_INF
7478 {"SC_INF", _SC_INF},
7479#endif
Fred Drakec9680921999-12-13 16:37:25 +00007480#ifdef _SC_INT_MAX
7481 {"SC_INT_MAX", _SC_INT_MAX},
7482#endif
7483#ifdef _SC_INT_MIN
7484 {"SC_INT_MIN", _SC_INT_MIN},
7485#endif
7486#ifdef _SC_IOV_MAX
7487 {"SC_IOV_MAX", _SC_IOV_MAX},
7488#endif
Fred Draked86ed291999-12-15 15:34:33 +00007489#ifdef _SC_IP_SECOPTS
7490 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7491#endif
Fred Drakec9680921999-12-13 16:37:25 +00007492#ifdef _SC_JOB_CONTROL
7493 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7494#endif
Fred Draked86ed291999-12-15 15:34:33 +00007495#ifdef _SC_KERN_POINTERS
7496 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7497#endif
7498#ifdef _SC_KERN_SIM
7499 {"SC_KERN_SIM", _SC_KERN_SIM},
7500#endif
Fred Drakec9680921999-12-13 16:37:25 +00007501#ifdef _SC_LINE_MAX
7502 {"SC_LINE_MAX", _SC_LINE_MAX},
7503#endif
7504#ifdef _SC_LOGIN_NAME_MAX
7505 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7506#endif
7507#ifdef _SC_LOGNAME_MAX
7508 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7509#endif
7510#ifdef _SC_LONG_BIT
7511 {"SC_LONG_BIT", _SC_LONG_BIT},
7512#endif
Fred Draked86ed291999-12-15 15:34:33 +00007513#ifdef _SC_MAC
7514 {"SC_MAC", _SC_MAC},
7515#endif
Fred Drakec9680921999-12-13 16:37:25 +00007516#ifdef _SC_MAPPED_FILES
7517 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7518#endif
7519#ifdef _SC_MAXPID
7520 {"SC_MAXPID", _SC_MAXPID},
7521#endif
7522#ifdef _SC_MB_LEN_MAX
7523 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7524#endif
7525#ifdef _SC_MEMLOCK
7526 {"SC_MEMLOCK", _SC_MEMLOCK},
7527#endif
7528#ifdef _SC_MEMLOCK_RANGE
7529 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7530#endif
7531#ifdef _SC_MEMORY_PROTECTION
7532 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7533#endif
7534#ifdef _SC_MESSAGE_PASSING
7535 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7536#endif
Fred Draked86ed291999-12-15 15:34:33 +00007537#ifdef _SC_MMAP_FIXED_ALIGNMENT
7538 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7539#endif
Fred Drakec9680921999-12-13 16:37:25 +00007540#ifdef _SC_MQ_OPEN_MAX
7541 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7542#endif
7543#ifdef _SC_MQ_PRIO_MAX
7544 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7545#endif
Fred Draked86ed291999-12-15 15:34:33 +00007546#ifdef _SC_NACLS_MAX
7547 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7548#endif
Fred Drakec9680921999-12-13 16:37:25 +00007549#ifdef _SC_NGROUPS_MAX
7550 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7551#endif
7552#ifdef _SC_NL_ARGMAX
7553 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7554#endif
7555#ifdef _SC_NL_LANGMAX
7556 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7557#endif
7558#ifdef _SC_NL_MSGMAX
7559 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7560#endif
7561#ifdef _SC_NL_NMAX
7562 {"SC_NL_NMAX", _SC_NL_NMAX},
7563#endif
7564#ifdef _SC_NL_SETMAX
7565 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7566#endif
7567#ifdef _SC_NL_TEXTMAX
7568 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7569#endif
7570#ifdef _SC_NPROCESSORS_CONF
7571 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7572#endif
7573#ifdef _SC_NPROCESSORS_ONLN
7574 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7575#endif
Fred Draked86ed291999-12-15 15:34:33 +00007576#ifdef _SC_NPROC_CONF
7577 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7578#endif
7579#ifdef _SC_NPROC_ONLN
7580 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7581#endif
Fred Drakec9680921999-12-13 16:37:25 +00007582#ifdef _SC_NZERO
7583 {"SC_NZERO", _SC_NZERO},
7584#endif
7585#ifdef _SC_OPEN_MAX
7586 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7587#endif
7588#ifdef _SC_PAGESIZE
7589 {"SC_PAGESIZE", _SC_PAGESIZE},
7590#endif
7591#ifdef _SC_PAGE_SIZE
7592 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7593#endif
7594#ifdef _SC_PASS_MAX
7595 {"SC_PASS_MAX", _SC_PASS_MAX},
7596#endif
7597#ifdef _SC_PHYS_PAGES
7598 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7599#endif
7600#ifdef _SC_PII
7601 {"SC_PII", _SC_PII},
7602#endif
7603#ifdef _SC_PII_INTERNET
7604 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7605#endif
7606#ifdef _SC_PII_INTERNET_DGRAM
7607 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7608#endif
7609#ifdef _SC_PII_INTERNET_STREAM
7610 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7611#endif
7612#ifdef _SC_PII_OSI
7613 {"SC_PII_OSI", _SC_PII_OSI},
7614#endif
7615#ifdef _SC_PII_OSI_CLTS
7616 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7617#endif
7618#ifdef _SC_PII_OSI_COTS
7619 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7620#endif
7621#ifdef _SC_PII_OSI_M
7622 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7623#endif
7624#ifdef _SC_PII_SOCKET
7625 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7626#endif
7627#ifdef _SC_PII_XTI
7628 {"SC_PII_XTI", _SC_PII_XTI},
7629#endif
7630#ifdef _SC_POLL
7631 {"SC_POLL", _SC_POLL},
7632#endif
7633#ifdef _SC_PRIORITIZED_IO
7634 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7635#endif
7636#ifdef _SC_PRIORITY_SCHEDULING
7637 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7638#endif
7639#ifdef _SC_REALTIME_SIGNALS
7640 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7641#endif
7642#ifdef _SC_RE_DUP_MAX
7643 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7644#endif
7645#ifdef _SC_RTSIG_MAX
7646 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7647#endif
7648#ifdef _SC_SAVED_IDS
7649 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7650#endif
7651#ifdef _SC_SCHAR_MAX
7652 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7653#endif
7654#ifdef _SC_SCHAR_MIN
7655 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7656#endif
7657#ifdef _SC_SELECT
7658 {"SC_SELECT", _SC_SELECT},
7659#endif
7660#ifdef _SC_SEMAPHORES
7661 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7662#endif
7663#ifdef _SC_SEM_NSEMS_MAX
7664 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7665#endif
7666#ifdef _SC_SEM_VALUE_MAX
7667 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7668#endif
7669#ifdef _SC_SHARED_MEMORY_OBJECTS
7670 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7671#endif
7672#ifdef _SC_SHRT_MAX
7673 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7674#endif
7675#ifdef _SC_SHRT_MIN
7676 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7677#endif
7678#ifdef _SC_SIGQUEUE_MAX
7679 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7680#endif
7681#ifdef _SC_SIGRT_MAX
7682 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7683#endif
7684#ifdef _SC_SIGRT_MIN
7685 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7686#endif
Fred Draked86ed291999-12-15 15:34:33 +00007687#ifdef _SC_SOFTPOWER
7688 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7689#endif
Fred Drakec9680921999-12-13 16:37:25 +00007690#ifdef _SC_SPLIT_CACHE
7691 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7692#endif
7693#ifdef _SC_SSIZE_MAX
7694 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7695#endif
7696#ifdef _SC_STACK_PROT
7697 {"SC_STACK_PROT", _SC_STACK_PROT},
7698#endif
7699#ifdef _SC_STREAM_MAX
7700 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7701#endif
7702#ifdef _SC_SYNCHRONIZED_IO
7703 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7704#endif
7705#ifdef _SC_THREADS
7706 {"SC_THREADS", _SC_THREADS},
7707#endif
7708#ifdef _SC_THREAD_ATTR_STACKADDR
7709 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7710#endif
7711#ifdef _SC_THREAD_ATTR_STACKSIZE
7712 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7713#endif
7714#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7715 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7716#endif
7717#ifdef _SC_THREAD_KEYS_MAX
7718 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7719#endif
7720#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7721 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7722#endif
7723#ifdef _SC_THREAD_PRIO_INHERIT
7724 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7725#endif
7726#ifdef _SC_THREAD_PRIO_PROTECT
7727 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7728#endif
7729#ifdef _SC_THREAD_PROCESS_SHARED
7730 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7731#endif
7732#ifdef _SC_THREAD_SAFE_FUNCTIONS
7733 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7734#endif
7735#ifdef _SC_THREAD_STACK_MIN
7736 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7737#endif
7738#ifdef _SC_THREAD_THREADS_MAX
7739 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7740#endif
7741#ifdef _SC_TIMERS
7742 {"SC_TIMERS", _SC_TIMERS},
7743#endif
7744#ifdef _SC_TIMER_MAX
7745 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7746#endif
7747#ifdef _SC_TTY_NAME_MAX
7748 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7749#endif
7750#ifdef _SC_TZNAME_MAX
7751 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7752#endif
7753#ifdef _SC_T_IOV_MAX
7754 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7755#endif
7756#ifdef _SC_UCHAR_MAX
7757 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7758#endif
7759#ifdef _SC_UINT_MAX
7760 {"SC_UINT_MAX", _SC_UINT_MAX},
7761#endif
7762#ifdef _SC_UIO_MAXIOV
7763 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7764#endif
7765#ifdef _SC_ULONG_MAX
7766 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7767#endif
7768#ifdef _SC_USHRT_MAX
7769 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7770#endif
7771#ifdef _SC_VERSION
7772 {"SC_VERSION", _SC_VERSION},
7773#endif
7774#ifdef _SC_WORD_BIT
7775 {"SC_WORD_BIT", _SC_WORD_BIT},
7776#endif
7777#ifdef _SC_XBS5_ILP32_OFF32
7778 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7779#endif
7780#ifdef _SC_XBS5_ILP32_OFFBIG
7781 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7782#endif
7783#ifdef _SC_XBS5_LP64_OFF64
7784 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7785#endif
7786#ifdef _SC_XBS5_LPBIG_OFFBIG
7787 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7788#endif
7789#ifdef _SC_XOPEN_CRYPT
7790 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7791#endif
7792#ifdef _SC_XOPEN_ENH_I18N
7793 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7794#endif
7795#ifdef _SC_XOPEN_LEGACY
7796 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7797#endif
7798#ifdef _SC_XOPEN_REALTIME
7799 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7800#endif
7801#ifdef _SC_XOPEN_REALTIME_THREADS
7802 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7803#endif
7804#ifdef _SC_XOPEN_SHM
7805 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7806#endif
7807#ifdef _SC_XOPEN_UNIX
7808 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7809#endif
7810#ifdef _SC_XOPEN_VERSION
7811 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7812#endif
7813#ifdef _SC_XOPEN_XCU_VERSION
7814 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7815#endif
7816#ifdef _SC_XOPEN_XPG2
7817 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7818#endif
7819#ifdef _SC_XOPEN_XPG3
7820 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7821#endif
7822#ifdef _SC_XOPEN_XPG4
7823 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7824#endif
7825};
7826
7827static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007828conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007829{
7830 return conv_confname(arg, valuep, posix_constants_sysconf,
7831 sizeof(posix_constants_sysconf)
7832 / sizeof(struct constdef));
7833}
7834
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007835PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007836"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007837Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007838
7839static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007840posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007841{
7842 PyObject *result = NULL;
7843 int name;
7844
7845 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7846 int value;
7847
7848 errno = 0;
7849 value = sysconf(name);
7850 if (value == -1 && errno != 0)
7851 posix_error();
7852 else
7853 result = PyInt_FromLong(value);
7854 }
7855 return result;
7856}
7857#endif
7858
7859
Fred Drakebec628d1999-12-15 18:31:10 +00007860/* This code is used to ensure that the tables of configuration value names
7861 * are in sorted order as required by conv_confname(), and also to build the
7862 * the exported dictionaries that are used to publish information about the
7863 * names available on the host platform.
7864 *
7865 * Sorting the table at runtime ensures that the table is properly ordered
7866 * when used, even for platforms we're not able to test on. It also makes
7867 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007868 */
Fred Drakebec628d1999-12-15 18:31:10 +00007869
7870static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007871cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007872{
7873 const struct constdef *c1 =
7874 (const struct constdef *) v1;
7875 const struct constdef *c2 =
7876 (const struct constdef *) v2;
7877
7878 return strcmp(c1->name, c2->name);
7879}
7880
7881static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007882setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007883 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007884{
Fred Drakebec628d1999-12-15 18:31:10 +00007885 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007886 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007887
7888 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7889 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007890 if (d == NULL)
7891 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007892
Barry Warsaw3155db32000-04-13 15:20:40 +00007893 for (i=0; i < tablesize; ++i) {
7894 PyObject *o = PyInt_FromLong(table[i].value);
7895 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7896 Py_XDECREF(o);
7897 Py_DECREF(d);
7898 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007899 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007900 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007901 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007902 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007903}
7904
Fred Drakebec628d1999-12-15 18:31:10 +00007905/* Return -1 on failure, 0 on success. */
7906static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007907setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007908{
7909#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007910 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007911 sizeof(posix_constants_pathconf)
7912 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007913 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007914 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007915#endif
7916#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007917 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007918 sizeof(posix_constants_confstr)
7919 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007920 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007921 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007922#endif
7923#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007924 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007925 sizeof(posix_constants_sysconf)
7926 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007927 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007928 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007929#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007930 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007931}
Fred Draked86ed291999-12-15 15:34:33 +00007932
7933
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007934PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007935"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007936Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007937in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007938
7939static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007940posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007941{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007942 abort();
7943 /*NOTREACHED*/
7944 Py_FatalError("abort() called from Python code didn't abort!");
7945 return NULL;
7946}
Fred Drakebec628d1999-12-15 18:31:10 +00007947
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007948#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007949PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007950"startfile(filepath [, operation]) - Start a file with its associated\n\
7951application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007952\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007953When \"operation\" is not specified or \"open\", this acts like\n\
7954double-clicking the file in Explorer, or giving the file name as an\n\
7955argument to the DOS \"start\" command: the file is opened with whatever\n\
7956application (if any) its extension is associated.\n\
7957When another \"operation\" is given, it specifies what should be done with\n\
7958the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007959\n\
7960startfile returns as soon as the associated application is launched.\n\
7961There is no option to wait for the application to close, and no way\n\
7962to retrieve the application's exit status.\n\
7963\n\
7964The filepath is relative to the current directory. If you want to use\n\
7965an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007966the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007967
7968static PyObject *
7969win32_startfile(PyObject *self, PyObject *args)
7970{
7971 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007972 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007973 HINSTANCE rc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007974#ifdef Py_WIN_WIDE_FILENAMES
7975 if (unicode_file_names()) {
7976 PyObject *unipath, *woperation = NULL;
7977 if (!PyArg_ParseTuple(args, "U|s:startfile",
7978 &unipath, &operation)) {
7979 PyErr_Clear();
7980 goto normal;
7981 }
7982
7983
7984 if (operation) {
7985 woperation = PyUnicode_DecodeASCII(operation,
7986 strlen(operation), NULL);
7987 if (!woperation) {
7988 PyErr_Clear();
7989 operation = NULL;
7990 goto normal;
7991 }
7992 }
7993
7994 Py_BEGIN_ALLOW_THREADS
7995 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7996 PyUnicode_AS_UNICODE(unipath),
7997 NULL, NULL, SW_SHOWNORMAL);
7998 Py_END_ALLOW_THREADS
7999
8000 Py_XDECREF(woperation);
8001 if (rc <= (HINSTANCE)32) {
8002 PyObject *errval = win32_error_unicode("startfile",
8003 PyUnicode_AS_UNICODE(unipath));
8004 return errval;
8005 }
8006 Py_INCREF(Py_None);
8007 return Py_None;
8008 }
8009#endif
8010
8011normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00008012 if (!PyArg_ParseTuple(args, "et|s:startfile",
8013 Py_FileSystemDefaultEncoding, &filepath,
8014 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00008015 return NULL;
8016 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00008017 rc = ShellExecute((HWND)0, operation, filepath,
8018 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008019 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00008020 if (rc <= (HINSTANCE)32) {
8021 PyObject *errval = win32_error("startfile", filepath);
8022 PyMem_Free(filepath);
8023 return errval;
8024 }
8025 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008026 Py_INCREF(Py_None);
8027 return Py_None;
8028}
8029#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008030
Martin v. Löwis438b5342002-12-27 10:16:42 +00008031#ifdef HAVE_GETLOADAVG
8032PyDoc_STRVAR(posix_getloadavg__doc__,
8033"getloadavg() -> (float, float, float)\n\n\
8034Return the number of processes in the system run queue averaged over\n\
8035the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8036was unobtainable");
8037
8038static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008039posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008040{
8041 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008042 if (getloadavg(loadavg, 3)!=3) {
8043 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8044 return NULL;
8045 } else
8046 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8047}
8048#endif
8049
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008050#ifdef MS_WINDOWS
8051
8052PyDoc_STRVAR(win32_urandom__doc__,
8053"urandom(n) -> str\n\n\
8054Return a string of n random bytes suitable for cryptographic use.");
8055
8056typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8057 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8058 DWORD dwFlags );
8059typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8060 BYTE *pbBuffer );
8061
8062static CRYPTGENRANDOM pCryptGenRandom = NULL;
8063static HCRYPTPROV hCryptProv = 0;
8064
Tim Peters4ad82172004-08-30 17:02:04 +00008065static PyObject*
8066win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008067{
Tim Petersd3115382004-08-30 17:36:46 +00008068 int howMany;
8069 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008070
Tim Peters4ad82172004-08-30 17:02:04 +00008071 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00008072 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00008073 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00008074 if (howMany < 0)
8075 return PyErr_Format(PyExc_ValueError,
8076 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008077
Tim Peters4ad82172004-08-30 17:02:04 +00008078 if (hCryptProv == 0) {
8079 HINSTANCE hAdvAPI32 = NULL;
8080 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008081
Tim Peters4ad82172004-08-30 17:02:04 +00008082 /* Obtain handle to the DLL containing CryptoAPI
8083 This should not fail */
8084 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8085 if(hAdvAPI32 == NULL)
8086 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008087
Tim Peters4ad82172004-08-30 17:02:04 +00008088 /* Obtain pointers to the CryptoAPI functions
8089 This will fail on some early versions of Win95 */
8090 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8091 hAdvAPI32,
8092 "CryptAcquireContextA");
8093 if (pCryptAcquireContext == NULL)
8094 return PyErr_Format(PyExc_NotImplementedError,
8095 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008096
Tim Peters4ad82172004-08-30 17:02:04 +00008097 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8098 hAdvAPI32, "CryptGenRandom");
Thomas Wouters89f507f2006-12-13 04:49:30 +00008099 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00008100 return PyErr_Format(PyExc_NotImplementedError,
8101 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008102
Tim Peters4ad82172004-08-30 17:02:04 +00008103 /* Acquire context */
8104 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8105 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8106 return win32_error("CryptAcquireContext", NULL);
8107 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008108
Tim Peters4ad82172004-08-30 17:02:04 +00008109 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00008110 result = PyString_FromStringAndSize(NULL, howMany);
8111 if (result != NULL) {
8112 /* Get random data */
8113 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
8114 PyString_AS_STRING(result))) {
8115 Py_DECREF(result);
8116 return win32_error("CryptGenRandom", NULL);
8117 }
Tim Peters4ad82172004-08-30 17:02:04 +00008118 }
Tim Petersd3115382004-08-30 17:36:46 +00008119 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008120}
8121#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008122
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008123#ifdef __VMS
8124/* Use openssl random routine */
8125#include <openssl/rand.h>
8126PyDoc_STRVAR(vms_urandom__doc__,
8127"urandom(n) -> str\n\n\
8128Return a string of n random bytes suitable for cryptographic use.");
8129
8130static PyObject*
8131vms_urandom(PyObject *self, PyObject *args)
8132{
8133 int howMany;
8134 PyObject* result;
8135
8136 /* Read arguments */
8137 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8138 return NULL;
8139 if (howMany < 0)
8140 return PyErr_Format(PyExc_ValueError,
8141 "negative argument not allowed");
8142
8143 /* Allocate bytes */
8144 result = PyString_FromStringAndSize(NULL, howMany);
8145 if (result != NULL) {
8146 /* Get random data */
8147 if (RAND_pseudo_bytes((unsigned char*)
8148 PyString_AS_STRING(result),
8149 howMany) < 0) {
8150 Py_DECREF(result);
8151 return PyErr_Format(PyExc_ValueError,
8152 "RAND_pseudo_bytes");
8153 }
8154 }
8155 return result;
8156}
8157#endif
8158
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008159static PyMethodDef posix_methods[] = {
8160 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8161#ifdef HAVE_TTYNAME
8162 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8163#endif
8164 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00008165#ifdef HAVE_CHFLAGS
8166 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8167#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008168 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008169#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008170 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008171#endif /* HAVE_CHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00008172#ifdef HAVE_LCHFLAGS
8173 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8174#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008175#ifdef HAVE_LCHOWN
8176 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8177#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008178#ifdef HAVE_CHROOT
8179 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8180#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008181#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00008182 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008183#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008184#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00008185 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008186#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00008187 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008188#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008189#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008190#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008191 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008192#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008193 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8194 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8195 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008196#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008197 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008198#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008199#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008200 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008201#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008202 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8203 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8204 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008205 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008206#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008207 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008208#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008209#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008210 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008211#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008212 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008213#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00008214 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008215#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008216 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8217 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8218 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008219#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00008220 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008221#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008222 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008223#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008224 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8225 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008226#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008227#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008228 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8229 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008230#if defined(PYOS_OS2)
8231 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8232 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8233#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008234#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008235#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008236 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008237#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008238#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008239 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008240#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008241#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008242 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008243#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008244#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008245 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008246#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008247#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008248 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008249#endif /* HAVE_GETEGID */
8250#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008251 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008252#endif /* HAVE_GETEUID */
8253#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008254 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008255#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008256#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008257 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008258#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008259 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008260#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008261 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008262#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008263#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008264 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008265#endif /* HAVE_GETPPID */
8266#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008267 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008268#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008269#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008270 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008271#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008272#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008273 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008274#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008275#ifdef HAVE_KILLPG
8276 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8277#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008278#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008279 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008280#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008281#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008282 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008283#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008284 {"popen2", win32_popen2, METH_VARARGS},
8285 {"popen3", win32_popen3, METH_VARARGS},
8286 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008287 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008288#else
8289#if defined(PYOS_OS2) && defined(PYCC_GCC)
8290 {"popen2", os2emx_popen2, METH_VARARGS},
8291 {"popen3", os2emx_popen3, METH_VARARGS},
8292 {"popen4", os2emx_popen4, METH_VARARGS},
8293#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008294#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008295#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008296#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008297 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008298#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008299#ifdef HAVE_SETEUID
8300 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8301#endif /* HAVE_SETEUID */
8302#ifdef HAVE_SETEGID
8303 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8304#endif /* HAVE_SETEGID */
8305#ifdef HAVE_SETREUID
8306 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8307#endif /* HAVE_SETREUID */
8308#ifdef HAVE_SETREGID
8309 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8310#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008311#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008312 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008313#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008314#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00008315 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008316#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008317#ifdef HAVE_GETPGID
8318 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8319#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008320#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008321 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008322#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008323#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008324 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008325#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008326#ifdef HAVE_WAIT3
8327 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8328#endif /* HAVE_WAIT3 */
8329#ifdef HAVE_WAIT4
8330 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8331#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008332#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008333 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008334#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008335#ifdef HAVE_GETSID
8336 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8337#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008338#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008339 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008340#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008341#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008342 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008343#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008344#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008345 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008346#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008347#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008348 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008349#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008350 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8351 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8352 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8353 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8354 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8355 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8356 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8357 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8358 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008359 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008360#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008361 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008362#endif
8363#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008364 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008365#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008366#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008367 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8368#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008369#ifdef HAVE_DEVICE_MACROS
8370 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8371 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8372 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8373#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008374#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008375 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008376#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008377#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008378 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008379#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008380#ifdef HAVE_UNSETENV
8381 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8382#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00008383#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008384 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00008385#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00008386#ifdef HAVE_FCHDIR
8387 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8388#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008389#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008390 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008391#endif
8392#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008393 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008394#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008395#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008396#ifdef WCOREDUMP
8397 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8398#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008399#ifdef WIFCONTINUED
8400 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8401#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008402#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008403 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008404#endif /* WIFSTOPPED */
8405#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008406 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008407#endif /* WIFSIGNALED */
8408#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008409 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008410#endif /* WIFEXITED */
8411#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008412 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008413#endif /* WEXITSTATUS */
8414#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008415 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008416#endif /* WTERMSIG */
8417#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008418 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008419#endif /* WSTOPSIG */
8420#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008421#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008422 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008423#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00008424#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008425 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008426#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008427#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008428 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008429#endif
8430#ifdef HAVE_TEMPNAM
8431 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8432#endif
8433#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008434 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008435#endif
Fred Drakec9680921999-12-13 16:37:25 +00008436#ifdef HAVE_CONFSTR
8437 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8438#endif
8439#ifdef HAVE_SYSCONF
8440 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8441#endif
8442#ifdef HAVE_FPATHCONF
8443 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8444#endif
8445#ifdef HAVE_PATHCONF
8446 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8447#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008448 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008449#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008450 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8451#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008452#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008453 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008454#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008455 #ifdef MS_WINDOWS
8456 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8457 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008458 #ifdef __VMS
8459 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8460 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008461 {NULL, NULL} /* Sentinel */
8462};
8463
8464
Barry Warsaw4a342091996-12-19 23:50:02 +00008465static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008466ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008467{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008468 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008469}
8470
Guido van Rossumd48f2521997-12-05 22:19:34 +00008471#if defined(PYOS_OS2)
8472/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008473static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008474{
8475 APIRET rc;
8476 ULONG values[QSV_MAX+1];
8477 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008478 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008479
8480 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008481 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008482 Py_END_ALLOW_THREADS
8483
8484 if (rc != NO_ERROR) {
8485 os2_error(rc);
8486 return -1;
8487 }
8488
Fred Drake4d1e64b2002-04-15 19:40:07 +00008489 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8490 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8491 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8492 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8493 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8494 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8495 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008496
8497 switch (values[QSV_VERSION_MINOR]) {
8498 case 0: ver = "2.00"; break;
8499 case 10: ver = "2.10"; break;
8500 case 11: ver = "2.11"; break;
8501 case 30: ver = "3.00"; break;
8502 case 40: ver = "4.00"; break;
8503 case 50: ver = "5.00"; break;
8504 default:
Tim Peters885d4572001-11-28 20:27:42 +00008505 PyOS_snprintf(tmp, sizeof(tmp),
8506 "%d-%d", values[QSV_VERSION_MAJOR],
8507 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008508 ver = &tmp[0];
8509 }
8510
8511 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008512 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008513 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008514
8515 /* Add Indicator of Which Drive was Used to Boot the System */
8516 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8517 tmp[1] = ':';
8518 tmp[2] = '\0';
8519
Fred Drake4d1e64b2002-04-15 19:40:07 +00008520 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008521}
8522#endif
8523
Barry Warsaw4a342091996-12-19 23:50:02 +00008524static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008525all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008526{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008527#ifdef F_OK
8528 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008529#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008530#ifdef R_OK
8531 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008532#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008533#ifdef W_OK
8534 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008535#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008536#ifdef X_OK
8537 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008538#endif
Fred Drakec9680921999-12-13 16:37:25 +00008539#ifdef NGROUPS_MAX
8540 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8541#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008542#ifdef TMP_MAX
8543 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8544#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008545#ifdef WCONTINUED
8546 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8547#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008548#ifdef WNOHANG
8549 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008550#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008551#ifdef WUNTRACED
8552 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8553#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008554#ifdef O_RDONLY
8555 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8556#endif
8557#ifdef O_WRONLY
8558 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8559#endif
8560#ifdef O_RDWR
8561 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8562#endif
8563#ifdef O_NDELAY
8564 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8565#endif
8566#ifdef O_NONBLOCK
8567 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8568#endif
8569#ifdef O_APPEND
8570 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8571#endif
8572#ifdef O_DSYNC
8573 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8574#endif
8575#ifdef O_RSYNC
8576 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8577#endif
8578#ifdef O_SYNC
8579 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8580#endif
8581#ifdef O_NOCTTY
8582 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8583#endif
8584#ifdef O_CREAT
8585 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8586#endif
8587#ifdef O_EXCL
8588 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8589#endif
8590#ifdef O_TRUNC
8591 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8592#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008593#ifdef O_BINARY
8594 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8595#endif
8596#ifdef O_TEXT
8597 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8598#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008599#ifdef O_LARGEFILE
8600 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8601#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008602#ifdef O_SHLOCK
8603 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8604#endif
8605#ifdef O_EXLOCK
8606 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8607#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008608
Tim Peters5aa91602002-01-30 05:46:57 +00008609/* MS Windows */
8610#ifdef O_NOINHERIT
8611 /* Don't inherit in child processes. */
8612 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8613#endif
8614#ifdef _O_SHORT_LIVED
8615 /* Optimize for short life (keep in memory). */
8616 /* MS forgot to define this one with a non-underscore form too. */
8617 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8618#endif
8619#ifdef O_TEMPORARY
8620 /* Automatically delete when last handle is closed. */
8621 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8622#endif
8623#ifdef O_RANDOM
8624 /* Optimize for random access. */
8625 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8626#endif
8627#ifdef O_SEQUENTIAL
8628 /* Optimize for sequential access. */
8629 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8630#endif
8631
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008632/* GNU extensions. */
8633#ifdef O_DIRECT
8634 /* Direct disk access. */
8635 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8636#endif
8637#ifdef O_DIRECTORY
8638 /* Must be a directory. */
8639 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8640#endif
8641#ifdef O_NOFOLLOW
8642 /* Do not follow links. */
8643 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8644#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008645
Barry Warsaw5676bd12003-01-07 20:57:09 +00008646 /* These come from sysexits.h */
8647#ifdef EX_OK
8648 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008649#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008650#ifdef EX_USAGE
8651 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008652#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008653#ifdef EX_DATAERR
8654 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008655#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008656#ifdef EX_NOINPUT
8657 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008658#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008659#ifdef EX_NOUSER
8660 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008661#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008662#ifdef EX_NOHOST
8663 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008664#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008665#ifdef EX_UNAVAILABLE
8666 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008667#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008668#ifdef EX_SOFTWARE
8669 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008670#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008671#ifdef EX_OSERR
8672 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008673#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008674#ifdef EX_OSFILE
8675 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008676#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008677#ifdef EX_CANTCREAT
8678 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008679#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008680#ifdef EX_IOERR
8681 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008682#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008683#ifdef EX_TEMPFAIL
8684 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008685#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008686#ifdef EX_PROTOCOL
8687 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008688#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008689#ifdef EX_NOPERM
8690 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008691#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008692#ifdef EX_CONFIG
8693 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008694#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008695#ifdef EX_NOTFOUND
8696 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008697#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008698
Guido van Rossum246bc171999-02-01 23:54:31 +00008699#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008700#if defined(PYOS_OS2) && defined(PYCC_GCC)
8701 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8702 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8703 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8704 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8705 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8706 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8707 if (ins(d, "P_PM", (long)P_PM)) return -1;
8708 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8709 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8710 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8711 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8712 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8713 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8714 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8715 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8716 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8717 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8718 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8719 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8720 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8721#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008722 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8723 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8724 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8725 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8726 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008727#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008728#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008729
Guido van Rossumd48f2521997-12-05 22:19:34 +00008730#if defined(PYOS_OS2)
8731 if (insertvalues(d)) return -1;
8732#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008733 return 0;
8734}
8735
8736
Tim Peters5aa91602002-01-30 05:46:57 +00008737#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008738#define INITFUNC initnt
8739#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008740
8741#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008742#define INITFUNC initos2
8743#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008744
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008745#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008746#define INITFUNC initposix
8747#define MODNAME "posix"
8748#endif
8749
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008750PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008751INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008752{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008753 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008754
Fred Drake4d1e64b2002-04-15 19:40:07 +00008755 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008756 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008757 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008758 if (m == NULL)
8759 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008760
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008761 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008762 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008763 Py_XINCREF(v);
8764 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008765 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008766 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008767
Fred Drake4d1e64b2002-04-15 19:40:07 +00008768 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008769 return;
8770
Fred Drake4d1e64b2002-04-15 19:40:07 +00008771 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008772 return;
8773
Fred Drake4d1e64b2002-04-15 19:40:07 +00008774 Py_INCREF(PyExc_OSError);
8775 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008776
Guido van Rossumb3d39562000-01-31 18:41:26 +00008777#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008778 if (posix_putenv_garbage == NULL)
8779 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008780#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008781
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008782 if (!initialized) {
8783 stat_result_desc.name = MODNAME ".stat_result";
8784 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8785 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8786 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8787 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8788 structseq_new = StatResultType.tp_new;
8789 StatResultType.tp_new = statresult_new;
8790
8791 statvfs_result_desc.name = MODNAME ".statvfs_result";
8792 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8793 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008794 Py_INCREF((PyObject*) &StatResultType);
8795 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008796 Py_INCREF((PyObject*) &StatVFSResultType);
8797 PyModule_AddObject(m, "statvfs_result",
8798 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008799 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008800
8801#ifdef __APPLE__
8802 /*
8803 * Step 2 of weak-linking support on Mac OS X.
8804 *
8805 * The code below removes functions that are not available on the
8806 * currently active platform.
8807 *
8808 * This block allow one to use a python binary that was build on
8809 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8810 * OSX 10.4.
8811 */
8812#ifdef HAVE_FSTATVFS
8813 if (fstatvfs == NULL) {
8814 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8815 return;
8816 }
8817 }
8818#endif /* HAVE_FSTATVFS */
8819
8820#ifdef HAVE_STATVFS
8821 if (statvfs == NULL) {
8822 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8823 return;
8824 }
8825 }
8826#endif /* HAVE_STATVFS */
8827
8828# ifdef HAVE_LCHOWN
8829 if (lchown == NULL) {
8830 if (PyObject_DelAttrString(m, "lchown") == -1) {
8831 return;
8832 }
8833 }
8834#endif /* HAVE_LCHOWN */
8835
8836
8837#endif /* __APPLE__ */
8838
Guido van Rossumb6775db1994-08-01 11:34:53 +00008839}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008840
8841#ifdef __cplusplus
8842}
8843#endif
8844
Thomas Wouters89f507f2006-12-13 04:49:30 +00008845