blob: 8fc9fa9b2fd62147eed6997be3df5cd97463c705 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Ronald Oussorend06b6f22006-04-23 11:59:25 +000016#ifdef __APPLE__
17 /*
18 * Step 1 of support for weak-linking a number of symbols existing on
19 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
31#include "structseq.h"
32
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Anthony Baxterac6bd462006-04-13 02:06:09 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047#ifndef Py_USING_UNICODE
48/* This is used in signatures of functions. */
49#define Py_UNICODE void
50#endif
51
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000052#if defined(PYOS_OS2)
53#define INCL_DOS
54#define INCL_DOSERRORS
55#define INCL_DOSPROCESS
56#define INCL_NOPMAPI
57#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#if defined(PYCC_GCC)
59#include <ctype.h>
60#include <io.h>
61#include <stdio.h>
62#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000063#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000064#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000065#endif
66
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000067#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/types.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000069#endif /* HAVE_SYS_TYPES_H */
70
71#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000072#include <sys/stat.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000073#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000074
Guido van Rossum36bc6801995-06-14 22:54:23 +000075#ifdef HAVE_SYS_WAIT_H
76#include <sys/wait.h> /* For WNOHANG */
77#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000078
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000079#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000080#include <signal.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000081#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000082
Guido van Rossumb6775db1994-08-01 11:34:53 +000083#ifdef HAVE_FCNTL_H
84#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000085#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000086
Guido van Rossuma6535fd2001-10-18 19:44:10 +000087#ifdef HAVE_GRP_H
88#include <grp.h>
89#endif
90
Barry Warsaw5676bd12003-01-07 20:57:09 +000091#ifdef HAVE_SYSEXITS_H
92#include <sysexits.h>
93#endif /* HAVE_SYSEXITS_H */
94
Anthony Baxter8a560de2004-10-13 15:30:56 +000095#ifdef HAVE_SYS_LOADAVG_H
96#include <sys/loadavg.h>
97#endif
98
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000100/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#include <process.h>
103#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000104#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#define HAVE_GETCWD 1
106#define HAVE_OPENDIR 1
107#define HAVE_SYSTEM 1
108#if defined(__OS2__)
109#define HAVE_EXECV 1
110#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#include <process.h>
113#else
114#ifdef __BORLANDC__ /* Borland compiler */
115#define HAVE_EXECV 1
116#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_OPENDIR 1
118#define HAVE_PIPE 1
119#define HAVE_POPEN 1
120#define HAVE_SYSTEM 1
121#define HAVE_WAIT 1
122#else
123#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000124#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000125#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000126#define HAVE_EXECV 1
127#define HAVE_PIPE 1
128#define HAVE_POPEN 1
129#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000130#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000131#define HAVE_FSYNC 1
132#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000133#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000134#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
135/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136#else /* all other compilers */
137/* Unix functions that the configure script doesn't check for */
138#define HAVE_EXECV 1
139#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000140#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
141#define HAVE_FORK1 1
142#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#define HAVE_GETCWD 1
144#define HAVE_GETEGID 1
145#define HAVE_GETEUID 1
146#define HAVE_GETGID 1
147#define HAVE_GETPPID 1
148#define HAVE_GETUID 1
149#define HAVE_KILL 1
150#define HAVE_OPENDIR 1
151#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000152#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000154#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#define HAVE_SYSTEM 1
156#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000157#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000158#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#endif /* _MSC_VER */
160#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000161#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000162#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000163
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000164#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000165
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000166#if defined(__sgi)&&_COMPILER_VERSION>=700
167/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
168 (default) */
169extern char *ctermid_r(char *);
170#endif
171
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000172#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000173#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000175#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000176#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000177extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000179extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000180#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000181#endif
182#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000183extern int chdir(char *);
184extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000185#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000186extern int chdir(const char *);
187extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000188#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000189#ifdef __BORLANDC__
190extern int chmod(const char *, int);
191#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000192extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000193#endif
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
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000256#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <direct.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000258#endif
259#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <io.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000261#endif
262#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <process.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +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 Wouters1ddba602006-04-25 15:29:46 +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 Wouters1ddba602006-04-25 15:29:46 +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
Neal Norwitzd5a37542006-03-20 06:48:34 +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{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +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. */
Martin v. Löwis8e0d4942006-05-04 10:08:42 +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 }
Martin v. Löwis8e0d4942006-05-04 10:08:42 +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 *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +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,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +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
Martin v. Löwis8e0d4942006-05-04 10:08:42 +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{
Martin v. Löwis77c176d2006-05-12 17:22:04 +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
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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;
Martin v. Löwisf43893a2006-10-09 20:44:25 +0000795 out = out * 10000000 + nsec_in / 100;
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000796 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000797}
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
Martin v. Löwis012bc722006-10-15 09:43:39 +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
Martin v. Löwis3bf573f2007-04-04 18:30:36 +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
Martin v. Löwis012bc722006-10-15 09:43:39 +0000883static BOOL WINAPI
884Py_GetFileAttributesExA(LPCSTR pszFile,
885 GET_FILEEX_INFO_LEVELS level,
886 LPVOID pv)
887{
888 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +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;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000910 return attributes_from_dir(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +0000911}
912
913static BOOL WINAPI
914Py_GetFileAttributesExW(LPCWSTR pszFile,
915 GET_FILEEX_INFO_LEVELS level,
916 LPVOID pv)
917{
918 BOOL result;
Martin v. Löwis012bc722006-10-15 09:43:39 +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;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000940 return attributes_from_dir_w(pszFile, pfad);
Martin v. Löwis012bc722006-10-15 09:43:39 +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 */
Martin v. Löwis012bc722006-10-15 09:43:39 +0000950 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +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 */
Martin v. Löwis012bc722006-10-15 09:43:39 +0000988 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Martin v. Löwis3bf573f2007-04-04 18:30:36 +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
Martin v. Löwis19ab6c92006-04-16 18:55:50 +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
Neal Norwitze0a81af2006-08-12 01:50:38 +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'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001377#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001378#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +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__,
Georg Brandl7a284472007-01-27 19:38:50 +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;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001509
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001510#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001518 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001519 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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. */
Martin v. Löwisee1e06d2006-07-02 18:44:00 +00001539 return PyBool_FromLong(!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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
Martin v. Löwis8e0d4942006-05-04 10:08:42 +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)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001629 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001630#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001631 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001632#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +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
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001708 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001709 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;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001723#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001724}
1725
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001726
Martin v. Löwis382abef2007-02-19 10:55:19 +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{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +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
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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];
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001913 wchar_t *wbuf2 = wbuf;
1914 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001915 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +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;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001988 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00001989 char *bufptr = namebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +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()) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001996 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001997 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1998 WIN32_FIND_DATAW wFileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001999 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002000 Py_UNICODE wch;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +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;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +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) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +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);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +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
Martin v. Löwis982e9fe2006-07-24 12:54:17 +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);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00002063 win32_error_unicode("FindClose", wnamebuf);
2064 free(wnamebuf);
2065 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002066 }
Martin v. Löwise3edaea2006-05-15 05:51:36 +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) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +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
Martin v. Löwis982e9fe2006-07-24 12:54:17 +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
Georg Brandl05e89b82006-04-11 07:04:06 +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 }
Georg Brandlbbfe4fa2006-04-11 06:47:43 +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. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002346 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002347 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002390#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002391}
2392
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002393
Neal Norwitz1818ed72006-03-26 00:29:48 +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
Neal Norwitz1818ed72006-03-26 00:29:48 +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
Martin v. Löwis8e0d4942006-05-04 10:08:42 +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
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +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
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002488 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002489#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +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
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002559 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002560#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +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__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +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{
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002644 NULL, OPEN_EXISTING,
2645 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002660 NULL, OPEN_EXISTING,
2661 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002689 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002690 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2691 &mtimesec, &musec) == -1)
2692 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002693 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +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);
Martin v. Löwis26fd9602006-04-22 11:15:41 +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;
Martin v. Löwis26fd9602006-04-22 11:15:41 +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;
Martin v. Löwis26fd9602006-04-22 11:15:41 +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);
Martin v. Löwis26fd9602006-04-22 11:15:41 +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
Neal Norwitz84a98e02006-04-10 07:44:23 +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));
Martin v. Löwis26fd9602006-04-22 11:15:41 +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) {
Tim Peters5aa91602002-01-30 05:46:57 +00004844 /* Eeek - file-not-found - possibly an embedding
4845 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004846 */
Tim Peters5aa91602002-01-30 05:46:57 +00004847 strncpy(modulepath,
4848 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004849 sizeof(modulepath)/sizeof(modulepath[0]));
4850 if (modulepath[strlen(modulepath)-1] != '\\')
4851 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004852 strncat(modulepath,
4853 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004854 (sizeof(modulepath)/sizeof(modulepath[0]))
4855 -strlen(modulepath));
4856 /* No where else to look - raise an easily identifiable
4857 error, rather than leaving Windows to report
4858 "file not found" - as the user is probably blissfully
4859 unaware this shim EXE is used, and it will confuse them.
4860 (well, it confused me for a while ;-)
4861 */
4862 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004863 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004864 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004865 "for popen to work with your shell "
4866 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004867 szConsoleSpawn);
4868 return FALSE;
4869 }
4870 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004871 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004872 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004873 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004874
Tim Peters92e4dd82002-10-05 01:47:34 +00004875 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004876 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004877 /* To maintain correct argument passing semantics,
4878 we pass the command-line as it stands, and allow
4879 quoting to be applied. w9xpopen.exe will then
4880 use its argv vector, and re-quote the necessary
4881 args for the ultimate child process.
4882 */
Tim Peters75cdad52001-11-28 22:07:30 +00004883 PyOS_snprintf(
4884 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004885 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004886 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004887 s1,
4888 s3,
4889 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004890 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004891 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004892 dialog:
4893 "Your program accessed mem currently in use at xxx"
4894 and a hopeful warning about the stability of your
4895 system.
4896 Cost is Ctrl+C wont kill children, but anyone
4897 who cares can have a go!
4898 */
4899 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004900 }
4901 }
4902
4903 /* Could be an else here to try cmd.exe / command.com in the path
4904 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004905 else {
Tim Peters402d5982001-08-27 06:37:48 +00004906 PyErr_SetString(PyExc_RuntimeError,
4907 "Cannot locate a COMSPEC environment variable to "
4908 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004909 return FALSE;
4910 }
Tim Peters5aa91602002-01-30 05:46:57 +00004911
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004912 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4913 siStartInfo.cb = sizeof(STARTUPINFO);
4914 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4915 siStartInfo.hStdInput = hStdin;
4916 siStartInfo.hStdOutput = hStdout;
4917 siStartInfo.hStdError = hStderr;
4918 siStartInfo.wShowWindow = SW_HIDE;
4919
4920 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004921 s2,
4922 NULL,
4923 NULL,
4924 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004925 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004926 NULL,
4927 NULL,
4928 &siStartInfo,
4929 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004930 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004931 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004932
Mark Hammondb37a3732000-08-14 04:47:33 +00004933 /* Return process handle */
4934 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004935 return TRUE;
4936 }
Tim Peters402d5982001-08-27 06:37:48 +00004937 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004938 return FALSE;
4939}
4940
4941/* The following code is based off of KB: Q190351 */
4942
4943static PyObject *
4944_PyPopen(char *cmdstring, int mode, int n)
4945{
4946 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4947 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004948 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004949
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004950 SECURITY_ATTRIBUTES saAttr;
4951 BOOL fSuccess;
4952 int fd1, fd2, fd3;
4953 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004954 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004955 PyObject *f;
4956
4957 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4958 saAttr.bInheritHandle = TRUE;
4959 saAttr.lpSecurityDescriptor = NULL;
4960
4961 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4962 return win32_error("CreatePipe", NULL);
4963
4964 /* Create new output read handle and the input write handle. Set
4965 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004966 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004967 * being created. */
4968 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004969 GetCurrentProcess(), &hChildStdinWrDup, 0,
4970 FALSE,
4971 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004972 if (!fSuccess)
4973 return win32_error("DuplicateHandle", NULL);
4974
4975 /* Close the inheritable version of ChildStdin
4976 that we're using. */
4977 CloseHandle(hChildStdinWr);
4978
4979 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4980 return win32_error("CreatePipe", NULL);
4981
4982 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004983 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4984 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004985 if (!fSuccess)
4986 return win32_error("DuplicateHandle", NULL);
4987
4988 /* Close the inheritable version of ChildStdout
4989 that we're using. */
4990 CloseHandle(hChildStdoutRd);
4991
4992 if (n != POPEN_4) {
4993 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4994 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004995 fSuccess = DuplicateHandle(GetCurrentProcess(),
4996 hChildStderrRd,
4997 GetCurrentProcess(),
4998 &hChildStderrRdDup, 0,
4999 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005000 if (!fSuccess)
5001 return win32_error("DuplicateHandle", NULL);
5002 /* Close the inheritable version of ChildStdErr that we're using. */
5003 CloseHandle(hChildStderrRd);
5004 }
Tim Peters5aa91602002-01-30 05:46:57 +00005005
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005006 switch (n) {
5007 case POPEN_1:
5008 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5009 case _O_WRONLY | _O_TEXT:
5010 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005011 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005012 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005013 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005014 PyFile_SetBufSize(f, 0);
5015 /* We don't care about these pipes anymore, so close them. */
5016 CloseHandle(hChildStdoutRdDup);
5017 CloseHandle(hChildStderrRdDup);
5018 break;
5019
5020 case _O_RDONLY | _O_TEXT:
5021 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005022 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005023 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005024 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005025 PyFile_SetBufSize(f, 0);
5026 /* We don't care about these pipes anymore, so close them. */
5027 CloseHandle(hChildStdinWrDup);
5028 CloseHandle(hChildStderrRdDup);
5029 break;
5030
5031 case _O_RDONLY | _O_BINARY:
5032 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005033 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005034 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005035 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005036 PyFile_SetBufSize(f, 0);
5037 /* We don't care about these pipes anymore, so close them. */
5038 CloseHandle(hChildStdinWrDup);
5039 CloseHandle(hChildStderrRdDup);
5040 break;
5041
5042 case _O_WRONLY | _O_BINARY:
5043 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005044 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005045 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00005046 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005047 PyFile_SetBufSize(f, 0);
5048 /* We don't care about these pipes anymore, so close them. */
5049 CloseHandle(hChildStdoutRdDup);
5050 CloseHandle(hChildStderrRdDup);
5051 break;
5052 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005053 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005054 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005055
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005056 case POPEN_2:
5057 case POPEN_4:
5058 {
5059 char *m1, *m2;
5060 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005061
Tim Peters7dca21e2002-08-19 00:42:29 +00005062 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005063 m1 = "r";
5064 m2 = "w";
5065 } else {
5066 m1 = "rb";
5067 m2 = "wb";
5068 }
5069
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005070 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005071 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005072 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005073 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005074 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005075 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00005076 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005077 PyFile_SetBufSize(p2, 0);
5078
5079 if (n != 4)
5080 CloseHandle(hChildStderrRdDup);
5081
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005082 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00005083 Py_XDECREF(p1);
5084 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00005085 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005086 break;
5087 }
Tim Peters5aa91602002-01-30 05:46:57 +00005088
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005089 case POPEN_3:
5090 {
5091 char *m1, *m2;
5092 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005093
Tim Peters7dca21e2002-08-19 00:42:29 +00005094 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005095 m1 = "r";
5096 m2 = "w";
5097 } else {
5098 m1 = "rb";
5099 m2 = "wb";
5100 }
5101
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005102 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005103 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005104 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005105 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005106 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005107 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005108 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00005109 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5110 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005111 PyFile_SetBufSize(p1, 0);
5112 PyFile_SetBufSize(p2, 0);
5113 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00005114 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00005115 Py_XDECREF(p1);
5116 Py_XDECREF(p2);
5117 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00005118 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005119 break;
5120 }
5121 }
5122
5123 if (n == POPEN_4) {
5124 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005125 hChildStdinRd,
5126 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005127 hChildStdoutWr,
5128 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005129 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005130 }
5131 else {
5132 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00005133 hChildStdinRd,
5134 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00005135 hChildStderrWr,
5136 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00005137 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005138 }
5139
Mark Hammondb37a3732000-08-14 04:47:33 +00005140 /*
5141 * Insert the files we've created into the process dictionary
5142 * all referencing the list with the process handle and the
5143 * initial number of files (see description below in _PyPclose).
5144 * Since if _PyPclose later tried to wait on a process when all
5145 * handles weren't closed, it could create a deadlock with the
5146 * child, we spend some energy here to try to ensure that we
5147 * either insert all file handles into the dictionary or none
5148 * at all. It's a little clumsy with the various popen modes
5149 * and variable number of files involved.
5150 */
5151 if (!_PyPopenProcs) {
5152 _PyPopenProcs = PyDict_New();
5153 }
5154
5155 if (_PyPopenProcs) {
5156 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5157 int ins_rc[3];
5158
5159 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5160 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5161
5162 procObj = PyList_New(2);
5163 hProcessObj = PyLong_FromVoidPtr(hProcess);
5164 intObj = PyInt_FromLong(file_count);
5165
5166 if (procObj && hProcessObj && intObj) {
5167 PyList_SetItem(procObj,0,hProcessObj);
5168 PyList_SetItem(procObj,1,intObj);
5169
5170 fileObj[0] = PyLong_FromVoidPtr(f1);
5171 if (fileObj[0]) {
5172 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5173 fileObj[0],
5174 procObj);
5175 }
5176 if (file_count >= 2) {
5177 fileObj[1] = PyLong_FromVoidPtr(f2);
5178 if (fileObj[1]) {
5179 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5180 fileObj[1],
5181 procObj);
5182 }
5183 }
5184 if (file_count >= 3) {
5185 fileObj[2] = PyLong_FromVoidPtr(f3);
5186 if (fileObj[2]) {
5187 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5188 fileObj[2],
5189 procObj);
5190 }
5191 }
5192
5193 if (ins_rc[0] < 0 || !fileObj[0] ||
5194 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5195 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5196 /* Something failed - remove any dictionary
5197 * entries that did make it.
5198 */
5199 if (!ins_rc[0] && fileObj[0]) {
5200 PyDict_DelItem(_PyPopenProcs,
5201 fileObj[0]);
5202 }
5203 if (!ins_rc[1] && fileObj[1]) {
5204 PyDict_DelItem(_PyPopenProcs,
5205 fileObj[1]);
5206 }
5207 if (!ins_rc[2] && fileObj[2]) {
5208 PyDict_DelItem(_PyPopenProcs,
5209 fileObj[2]);
5210 }
5211 }
5212 }
Tim Peters5aa91602002-01-30 05:46:57 +00005213
Mark Hammondb37a3732000-08-14 04:47:33 +00005214 /*
5215 * Clean up our localized references for the dictionary keys
5216 * and value since PyDict_SetItem will Py_INCREF any copies
5217 * that got placed in the dictionary.
5218 */
5219 Py_XDECREF(procObj);
5220 Py_XDECREF(fileObj[0]);
5221 Py_XDECREF(fileObj[1]);
5222 Py_XDECREF(fileObj[2]);
5223 }
5224
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005225 /* Child is launched. Close the parents copy of those pipe
5226 * handles that only the child should have open. You need to
5227 * make sure that no handles to the write end of the output pipe
5228 * are maintained in this process or else the pipe will not close
5229 * when the child process exits and the ReadFile will hang. */
5230
5231 if (!CloseHandle(hChildStdinRd))
5232 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005233
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005234 if (!CloseHandle(hChildStdoutWr))
5235 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005236
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005237 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5238 return win32_error("CloseHandle", NULL);
5239
5240 return f;
5241}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005242
5243/*
5244 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5245 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005246 *
5247 * This function uses the _PyPopenProcs dictionary in order to map the
5248 * input file pointer to information about the process that was
5249 * originally created by the popen* call that created the file pointer.
5250 * The dictionary uses the file pointer as a key (with one entry
5251 * inserted for each file returned by the original popen* call) and a
5252 * single list object as the value for all files from a single call.
5253 * The list object contains the Win32 process handle at [0], and a file
5254 * count at [1], which is initialized to the total number of file
5255 * handles using that list.
5256 *
5257 * This function closes whichever handle it is passed, and decrements
5258 * the file count in the dictionary for the process handle pointed to
5259 * by this file. On the last close (when the file count reaches zero),
5260 * this function will wait for the child process and then return its
5261 * exit code as the result of the close() operation. This permits the
5262 * files to be closed in any order - it is always the close() of the
5263 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005264 *
5265 * NOTE: This function is currently called with the GIL released.
5266 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005267 */
Tim Peters736aa322000-09-01 06:51:24 +00005268
Fredrik Lundh56055a42000-07-23 19:47:12 +00005269static int _PyPclose(FILE *file)
5270{
Fredrik Lundh20318932000-07-26 17:29:12 +00005271 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005272 DWORD exit_code;
5273 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005274 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5275 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005276#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005277 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005278#endif
5279
Fredrik Lundh20318932000-07-26 17:29:12 +00005280 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005281 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005282 */
5283 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005284#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005285 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005286#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005287 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005288 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5289 (procObj = PyDict_GetItem(_PyPopenProcs,
5290 fileObj)) != NULL &&
5291 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5292 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5293
5294 hProcess = PyLong_AsVoidPtr(hProcessObj);
5295 file_count = PyInt_AsLong(intObj);
5296
5297 if (file_count > 1) {
5298 /* Still other files referencing process */
5299 file_count--;
5300 PyList_SetItem(procObj,1,
5301 PyInt_FromLong(file_count));
5302 } else {
5303 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005304 if (result != EOF &&
5305 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5306 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005307 /* Possible truncation here in 16-bit environments, but
5308 * real exit codes are just the lower byte in any event.
5309 */
5310 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005311 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005312 /* Indicate failure - this will cause the file object
5313 * to raise an I/O error and translate the last Win32
5314 * error code from errno. We do have a problem with
5315 * last errors that overlap the normal errno table,
5316 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005317 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005318 if (result != EOF) {
5319 /* If the error wasn't from the fclose(), then
5320 * set errno for the file object error handling.
5321 */
5322 errno = GetLastError();
5323 }
5324 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005325 }
5326
5327 /* Free up the native handle at this point */
5328 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005329 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005330
Mark Hammondb37a3732000-08-14 04:47:33 +00005331 /* Remove this file pointer from dictionary */
5332 PyDict_DelItem(_PyPopenProcs, fileObj);
5333
5334 if (PyDict_Size(_PyPopenProcs) == 0) {
5335 Py_DECREF(_PyPopenProcs);
5336 _PyPopenProcs = NULL;
5337 }
5338
5339 } /* if object retrieval ok */
5340
5341 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005342 } /* if _PyPopenProcs */
5343
Tim Peters736aa322000-09-01 06:51:24 +00005344#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005345 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005346#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005347 return result;
5348}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005349
5350#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005351static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005352posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005353{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005354 char *name;
5355 char *mode = "r";
5356 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005357 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005358 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005359 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005360 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005361 /* Strip mode of binary or text modifiers */
5362 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5363 mode = "r";
5364 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5365 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005366 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005367 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005368 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005369 if (fp == NULL)
5370 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005371 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005372 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005373 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005374 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005375}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005376
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005377#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005378#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005379
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005380
Guido van Rossumb6775db1994-08-01 11:34:53 +00005381#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005382PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005383"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005384Set the current process's user id.");
5385
Barry Warsaw53699e91996-12-10 23:23:01 +00005386static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005387posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005388{
5389 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005390 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005391 return NULL;
5392 if (setuid(uid) < 0)
5393 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005394 Py_INCREF(Py_None);
5395 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005396}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005397#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005398
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005399
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005400#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005401PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005402"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005403Set the current process's effective user id.");
5404
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005405static PyObject *
5406posix_seteuid (PyObject *self, PyObject *args)
5407{
5408 int euid;
5409 if (!PyArg_ParseTuple(args, "i", &euid)) {
5410 return NULL;
5411 } else if (seteuid(euid) < 0) {
5412 return posix_error();
5413 } else {
5414 Py_INCREF(Py_None);
5415 return Py_None;
5416 }
5417}
5418#endif /* HAVE_SETEUID */
5419
5420#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005421PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005422"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005423Set the current process's effective group id.");
5424
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005425static PyObject *
5426posix_setegid (PyObject *self, PyObject *args)
5427{
5428 int egid;
5429 if (!PyArg_ParseTuple(args, "i", &egid)) {
5430 return NULL;
5431 } else if (setegid(egid) < 0) {
5432 return posix_error();
5433 } else {
5434 Py_INCREF(Py_None);
5435 return Py_None;
5436 }
5437}
5438#endif /* HAVE_SETEGID */
5439
5440#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005441PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005442"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005443Set the current process's real and effective user ids.");
5444
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005445static PyObject *
5446posix_setreuid (PyObject *self, PyObject *args)
5447{
5448 int ruid, euid;
5449 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5450 return NULL;
5451 } else if (setreuid(ruid, euid) < 0) {
5452 return posix_error();
5453 } else {
5454 Py_INCREF(Py_None);
5455 return Py_None;
5456 }
5457}
5458#endif /* HAVE_SETREUID */
5459
5460#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005461PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005462"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005463Set the current process's real and effective group ids.");
5464
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005465static PyObject *
5466posix_setregid (PyObject *self, PyObject *args)
5467{
5468 int rgid, egid;
5469 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5470 return NULL;
5471 } else if (setregid(rgid, egid) < 0) {
5472 return posix_error();
5473 } else {
5474 Py_INCREF(Py_None);
5475 return Py_None;
5476 }
5477}
5478#endif /* HAVE_SETREGID */
5479
Guido van Rossumb6775db1994-08-01 11:34:53 +00005480#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005481PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005482"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005483Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005484
Barry Warsaw53699e91996-12-10 23:23:01 +00005485static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005486posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005487{
5488 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005489 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005490 return NULL;
5491 if (setgid(gid) < 0)
5492 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005493 Py_INCREF(Py_None);
5494 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005495}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005496#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005497
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005498#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005499PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005500"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005501Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005502
5503static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005504posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005505{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005506 int i, len;
5507 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005508
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005509 if (!PySequence_Check(groups)) {
5510 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5511 return NULL;
5512 }
5513 len = PySequence_Size(groups);
5514 if (len > MAX_GROUPS) {
5515 PyErr_SetString(PyExc_ValueError, "too many groups");
5516 return NULL;
5517 }
5518 for(i = 0; i < len; i++) {
5519 PyObject *elem;
5520 elem = PySequence_GetItem(groups, i);
5521 if (!elem)
5522 return NULL;
5523 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +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");
5534 Py_DECREF(elem);
5535 return NULL;
5536 }
5537 grouplist[i] = x;
5538 /* read back the value to see if it fitted in gid_t */
5539 if (grouplist[i] != x) {
5540 PyErr_SetString(PyExc_TypeError,
5541 "group id too big");
5542 Py_DECREF(elem);
5543 return NULL;
5544 }
5545 }
5546 } else {
5547 long x = PyInt_AsLong(elem);
5548 grouplist[i] = x;
5549 if (grouplist[i] != x) {
5550 PyErr_SetString(PyExc_TypeError,
5551 "group id too big");
5552 Py_DECREF(elem);
5553 return NULL;
5554 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005555 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005556 Py_DECREF(elem);
5557 }
5558
5559 if (setgroups(len, grouplist) < 0)
5560 return posix_error();
5561 Py_INCREF(Py_None);
5562 return Py_None;
5563}
5564#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005565
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005566#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005567static PyObject *
5568wait_helper(int pid, int status, struct rusage *ru)
5569{
5570 PyObject *result;
5571 static PyObject *struct_rusage;
5572
5573 if (pid == -1)
5574 return posix_error();
5575
5576 if (struct_rusage == NULL) {
5577 PyObject *m = PyImport_ImportModule("resource");
5578 if (m == NULL)
5579 return NULL;
5580 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5581 Py_DECREF(m);
5582 if (struct_rusage == NULL)
5583 return NULL;
5584 }
5585
5586 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5587 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5588 if (!result)
5589 return NULL;
5590
5591#ifndef doubletime
5592#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5593#endif
5594
5595 PyStructSequence_SET_ITEM(result, 0,
5596 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5597 PyStructSequence_SET_ITEM(result, 1,
5598 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5599#define SET_INT(result, index, value)\
5600 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5601 SET_INT(result, 2, ru->ru_maxrss);
5602 SET_INT(result, 3, ru->ru_ixrss);
5603 SET_INT(result, 4, ru->ru_idrss);
5604 SET_INT(result, 5, ru->ru_isrss);
5605 SET_INT(result, 6, ru->ru_minflt);
5606 SET_INT(result, 7, ru->ru_majflt);
5607 SET_INT(result, 8, ru->ru_nswap);
5608 SET_INT(result, 9, ru->ru_inblock);
5609 SET_INT(result, 10, ru->ru_oublock);
5610 SET_INT(result, 11, ru->ru_msgsnd);
5611 SET_INT(result, 12, ru->ru_msgrcv);
5612 SET_INT(result, 13, ru->ru_nsignals);
5613 SET_INT(result, 14, ru->ru_nvcsw);
5614 SET_INT(result, 15, ru->ru_nivcsw);
5615#undef SET_INT
5616
5617 if (PyErr_Occurred()) {
5618 Py_DECREF(result);
5619 return NULL;
5620 }
5621
Neal Norwitz9b00a562006-03-20 08:47:12 +00005622 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005623}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005624#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005625
5626#ifdef HAVE_WAIT3
5627PyDoc_STRVAR(posix_wait3__doc__,
5628"wait3(options) -> (pid, status, rusage)\n\n\
5629Wait for completion of a child process.");
5630
5631static PyObject *
5632posix_wait3(PyObject *self, PyObject *args)
5633{
5634 int pid, options;
5635 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005636 WAIT_TYPE status;
5637 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005638
5639 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5640 return NULL;
5641
5642 Py_BEGIN_ALLOW_THREADS
5643 pid = wait3(&status, options, &ru);
5644 Py_END_ALLOW_THREADS
5645
Neal Norwitzd5a37542006-03-20 06:48:34 +00005646 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005647}
5648#endif /* HAVE_WAIT3 */
5649
5650#ifdef HAVE_WAIT4
5651PyDoc_STRVAR(posix_wait4__doc__,
5652"wait4(pid, options) -> (pid, status, rusage)\n\n\
5653Wait for completion of a given child process.");
5654
5655static PyObject *
5656posix_wait4(PyObject *self, PyObject *args)
5657{
5658 int pid, options;
5659 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005660 WAIT_TYPE status;
5661 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005662
5663 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5664 return NULL;
5665
5666 Py_BEGIN_ALLOW_THREADS
5667 pid = wait4(pid, &status, options, &ru);
5668 Py_END_ALLOW_THREADS
5669
Neal Norwitzd5a37542006-03-20 06:48:34 +00005670 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005671}
5672#endif /* HAVE_WAIT4 */
5673
Guido van Rossumb6775db1994-08-01 11:34:53 +00005674#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005675PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005676"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005677Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005678
Barry Warsaw53699e91996-12-10 23:23:01 +00005679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005680posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005681{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005682 int pid, options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005683 WAIT_TYPE status;
5684 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005685
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005686 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005687 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005688 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005689 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005690 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005691 if (pid == -1)
5692 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005693
5694 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005695}
5696
Tim Petersab034fa2002-02-01 11:27:43 +00005697#elif defined(HAVE_CWAIT)
5698
5699/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005700PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005701"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005702"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005703
5704static PyObject *
5705posix_waitpid(PyObject *self, PyObject *args)
5706{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005707 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005708 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005709
5710 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5711 return NULL;
5712 Py_BEGIN_ALLOW_THREADS
5713 pid = _cwait(&status, pid, options);
5714 Py_END_ALLOW_THREADS
5715 if (pid == -1)
5716 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005717
5718 /* shift the status left a byte so this is more like the POSIX waitpid */
5719 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005720}
5721#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005722
Guido van Rossumad0ee831995-03-01 10:34:45 +00005723#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005724PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005725"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005726Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005727
Barry Warsaw53699e91996-12-10 23:23:01 +00005728static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005729posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005730{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005731 int pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005732 WAIT_TYPE status;
5733 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005734
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005735 Py_BEGIN_ALLOW_THREADS
5736 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005737 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005738 if (pid == -1)
5739 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005740
5741 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005742}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005743#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005744
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005745
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005746PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005747"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005748Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005749
Barry Warsaw53699e91996-12-10 23:23:01 +00005750static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005751posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005752{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005753#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005754 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005755#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005756#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005757 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005758#else
5759 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5760#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005761#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005762}
5763
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005764
Guido van Rossumb6775db1994-08-01 11:34:53 +00005765#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005766PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005767"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005768Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005769
Barry Warsaw53699e91996-12-10 23:23:01 +00005770static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005771posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005772{
Ronald Oussoren10168f22006-10-22 10:45:18 +00005773 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005774 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005775 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005776 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005777#ifdef Py_USING_UNICODE
5778 int arg_is_unicode = 0;
5779#endif
5780
5781 if (!PyArg_ParseTuple(args, "et:readlink",
5782 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005783 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00005784#ifdef Py_USING_UNICODE
5785 v = PySequence_GetItem(args, 0);
5786 if (v == NULL) return NULL;
5787
5788 if (PyUnicode_Check(v)) {
5789 arg_is_unicode = 1;
5790 }
5791 Py_DECREF(v);
5792#endif
5793
Barry Warsaw53699e91996-12-10 23:23:01 +00005794 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005795 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005796 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005797 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005798 return posix_error_with_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00005799
5800 v = PyString_FromStringAndSize(buf, n);
5801#ifdef Py_USING_UNICODE
5802 if (arg_is_unicode) {
5803 PyObject *w;
5804
5805 w = PyUnicode_FromEncodedObject(v,
5806 Py_FileSystemDefaultEncoding,
5807 "strict");
5808 if (w != NULL) {
5809 Py_DECREF(v);
5810 v = w;
5811 }
5812 else {
5813 /* fall back to the original byte string, as
5814 discussed in patch #683592 */
5815 PyErr_Clear();
5816 }
5817 }
5818#endif
5819 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005820}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005821#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005822
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005823
Guido van Rossumb6775db1994-08-01 11:34:53 +00005824#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005825PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005826"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005827Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005828
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005830posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005831{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00005832 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005833}
5834#endif /* HAVE_SYMLINK */
5835
5836
5837#ifdef HAVE_TIMES
5838#ifndef HZ
5839#define HZ 60 /* Universal constant :-) */
5840#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005841
Guido van Rossumd48f2521997-12-05 22:19:34 +00005842#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5843static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005844system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005845{
5846 ULONG value = 0;
5847
5848 Py_BEGIN_ALLOW_THREADS
5849 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5850 Py_END_ALLOW_THREADS
5851
5852 return value;
5853}
5854
5855static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005856posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005857{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005858 /* Currently Only Uptime is Provided -- Others Later */
5859 return Py_BuildValue("ddddd",
5860 (double)0 /* t.tms_utime / HZ */,
5861 (double)0 /* t.tms_stime / HZ */,
5862 (double)0 /* t.tms_cutime / HZ */,
5863 (double)0 /* t.tms_cstime / HZ */,
5864 (double)system_uptime() / 1000);
5865}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005866#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005867static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005868posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005869{
5870 struct tms t;
5871 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005872 errno = 0;
5873 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005874 if (c == (clock_t) -1)
5875 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005876 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005877 (double)t.tms_utime / HZ,
5878 (double)t.tms_stime / HZ,
5879 (double)t.tms_cutime / HZ,
5880 (double)t.tms_cstime / HZ,
5881 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005882}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005883#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005884#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005885
5886
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005887#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005888#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005889static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005890posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005891{
5892 FILETIME create, exit, kernel, user;
5893 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005894 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005895 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5896 /* The fields of a FILETIME structure are the hi and lo part
5897 of a 64-bit value expressed in 100 nanosecond units.
5898 1e7 is one second in such units; 1e-7 the inverse.
5899 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5900 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005901 return Py_BuildValue(
5902 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005903 (double)(kernel.dwHighDateTime*429.4967296 +
5904 kernel.dwLowDateTime*1e-7),
5905 (double)(user.dwHighDateTime*429.4967296 +
5906 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005907 (double)0,
5908 (double)0,
5909 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005910}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005911#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005912
5913#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005914PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005915"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005916Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005917#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005918
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005919
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005920#ifdef HAVE_GETSID
5921PyDoc_STRVAR(posix_getsid__doc__,
5922"getsid(pid) -> sid\n\n\
5923Call the system call getsid().");
5924
5925static PyObject *
5926posix_getsid(PyObject *self, PyObject *args)
5927{
5928 int pid, sid;
5929 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5930 return NULL;
5931 sid = getsid(pid);
5932 if (sid < 0)
5933 return posix_error();
5934 return PyInt_FromLong((long)sid);
5935}
5936#endif /* HAVE_GETSID */
5937
5938
Guido van Rossumb6775db1994-08-01 11:34:53 +00005939#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005940PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005941"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005942Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005943
Barry Warsaw53699e91996-12-10 23:23:01 +00005944static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005945posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005946{
Guido van Rossum687dd131993-05-17 08:34:16 +00005947 if (setsid() < 0)
5948 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005949 Py_INCREF(Py_None);
5950 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005951}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005952#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005953
Guido van Rossumb6775db1994-08-01 11:34:53 +00005954#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005955PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005956"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005957Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005958
Barry Warsaw53699e91996-12-10 23:23:01 +00005959static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005960posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005961{
5962 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005963 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005964 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005965 if (setpgid(pid, pgrp) < 0)
5966 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005967 Py_INCREF(Py_None);
5968 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005969}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005970#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005971
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005972
Guido van Rossumb6775db1994-08-01 11:34:53 +00005973#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005974PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005975"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005976Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005977
Barry Warsaw53699e91996-12-10 23:23:01 +00005978static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005979posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005980{
5981 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005982 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005983 return NULL;
5984 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005985 if (pgid < 0)
5986 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005987 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005988}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005989#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005990
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005991
Guido van Rossumb6775db1994-08-01 11:34:53 +00005992#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005993PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005994"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005995Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005996
Barry Warsaw53699e91996-12-10 23:23:01 +00005997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005998posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005999{
6000 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006001 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00006002 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006003 if (tcsetpgrp(fd, pgid) < 0)
6004 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00006005 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00006006 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006007}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006008#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006009
Guido van Rossum687dd131993-05-17 08:34:16 +00006010/* Functions acting on file descriptors */
6011
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006012PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006013"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006014Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006015
Barry Warsaw53699e91996-12-10 23:23:01 +00006016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006017posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006018{
Mark Hammondef8b6542001-05-13 08:04:26 +00006019 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006020 int flag;
6021 int mode = 0777;
6022 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006023
6024#ifdef MS_WINDOWS
6025 if (unicode_file_names()) {
6026 PyUnicodeObject *po;
6027 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6028 Py_BEGIN_ALLOW_THREADS
6029 /* PyUnicode_AS_UNICODE OK without thread
6030 lock as it is a simple dereference. */
6031 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6032 Py_END_ALLOW_THREADS
6033 if (fd < 0)
6034 return posix_error();
6035 return PyInt_FromLong((long)fd);
6036 }
6037 /* Drop the argument parsing error as narrow strings
6038 are also valid. */
6039 PyErr_Clear();
6040 }
6041#endif
6042
Tim Peters5aa91602002-01-30 05:46:57 +00006043 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00006044 Py_FileSystemDefaultEncoding, &file,
6045 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00006046 return NULL;
6047
Barry Warsaw53699e91996-12-10 23:23:01 +00006048 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006049 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00006050 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006051 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00006052 return posix_error_with_allocated_filename(file);
6053 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00006054 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006055}
6056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006057
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006058PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006059"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006060Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006061
Barry Warsaw53699e91996-12-10 23:23:01 +00006062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006063posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006064{
6065 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006066 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006067 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006068 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006069 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006070 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006071 if (res < 0)
6072 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006073 Py_INCREF(Py_None);
6074 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006075}
6076
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006077
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006078PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006079"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006080Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006081
Barry Warsaw53699e91996-12-10 23:23:01 +00006082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006083posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006084{
6085 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006086 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006087 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006088 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006089 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00006090 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006091 if (fd < 0)
6092 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006093 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006094}
6095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006096
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006097PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006098"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006099Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006100
Barry Warsaw53699e91996-12-10 23:23:01 +00006101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006102posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006103{
6104 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006105 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00006106 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006107 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006108 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00006109 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006110 if (res < 0)
6111 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006112 Py_INCREF(Py_None);
6113 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006114}
6115
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006116
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006117PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006118"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006119Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006120
Barry Warsaw53699e91996-12-10 23:23:01 +00006121static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006122posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006123{
6124 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006125#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006126 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006127#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00006128 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006129#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006130 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006131 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00006132 return NULL;
6133#ifdef SEEK_SET
6134 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6135 switch (how) {
6136 case 0: how = SEEK_SET; break;
6137 case 1: how = SEEK_CUR; break;
6138 case 2: how = SEEK_END; break;
6139 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006140#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006141
6142#if !defined(HAVE_LARGEFILE_SUPPORT)
6143 pos = PyInt_AsLong(posobj);
6144#else
6145 pos = PyLong_Check(posobj) ?
6146 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6147#endif
6148 if (PyErr_Occurred())
6149 return NULL;
6150
Barry Warsaw53699e91996-12-10 23:23:01 +00006151 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006152#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00006153 res = _lseeki64(fd, pos, how);
6154#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006155 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006156#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006157 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006158 if (res < 0)
6159 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006160
6161#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00006162 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006163#else
6164 return PyLong_FromLongLong(res);
6165#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006166}
6167
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006168
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006169PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006170"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006171Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006172
Barry Warsaw53699e91996-12-10 23:23:01 +00006173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006174posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006175{
Guido van Rossum8bac5461996-06-11 18:38:48 +00006176 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00006177 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006178 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006179 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00006180 if (size < 0) {
6181 errno = EINVAL;
6182 return posix_error();
6183 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006184 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006185 if (buffer == NULL)
6186 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006187 Py_BEGIN_ALLOW_THREADS
6188 n = read(fd, PyString_AsString(buffer), size);
6189 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00006190 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006191 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00006192 return posix_error();
6193 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00006194 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00006195 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00006196 return buffer;
6197}
6198
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006199
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006200PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006201"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006202Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006203
Barry Warsaw53699e91996-12-10 23:23:01 +00006204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006205posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006206{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006207 int fd;
6208 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00006209 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006210
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006211 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00006212 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006213 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006214 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00006215 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006216 if (size < 0)
6217 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006218 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006219}
6220
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006221
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006222PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006223"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006224Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006225
Barry Warsaw53699e91996-12-10 23:23:01 +00006226static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006227posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006228{
6229 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006230 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006231 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006232 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006233 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006234#ifdef __VMS
6235 /* on OpenVMS we must ensure that all bytes are written to the file */
6236 fsync(fd);
6237#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006238 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006239 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006240 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006241 if (res != 0) {
6242#ifdef MS_WINDOWS
6243 return win32_error("fstat", NULL);
6244#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006245 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006246#endif
6247 }
Tim Peters5aa91602002-01-30 05:46:57 +00006248
Martin v. Löwis14694662006-02-03 12:54:16 +00006249 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006250}
6251
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006252
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006253PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006254"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006255Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006256
Barry Warsaw53699e91996-12-10 23:23:01 +00006257static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006258posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006259{
Guido van Rossum687dd131993-05-17 08:34:16 +00006260 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006261 char *mode = "r";
6262 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006263 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006264 PyObject *f;
6265 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006266 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006267
Thomas Heller1f043e22002-11-07 16:00:59 +00006268 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
6269 PyErr_Format(PyExc_ValueError,
6270 "invalid file mode '%s'", mode);
6271 return NULL;
6272 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006273 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006274#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006275 if (mode[0] == 'a') {
6276 /* try to make sure the O_APPEND flag is set */
6277 int flags;
6278 flags = fcntl(fd, F_GETFL);
6279 if (flags != -1)
6280 fcntl(fd, F_SETFL, flags | O_APPEND);
6281 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006282 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006283 /* restore old mode if fdopen failed */
6284 fcntl(fd, F_SETFL, flags);
6285 } else {
6286 fp = fdopen(fd, mode);
6287 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006288#else
6289 fp = fdopen(fd, mode);
6290#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006291 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006292 if (fp == NULL)
6293 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00006294 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006295 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006296 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006297 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006298}
6299
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006300PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006301"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006302Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006303connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006304
6305static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006306posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006307{
6308 int fd;
6309 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6310 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006311 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006312}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006313
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006314#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006315PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006316"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006317Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006318
Barry Warsaw53699e91996-12-10 23:23:01 +00006319static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006320posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006321{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006322#if defined(PYOS_OS2)
6323 HFILE read, write;
6324 APIRET rc;
6325
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006326 Py_BEGIN_ALLOW_THREADS
6327 rc = DosCreatePipe( &read, &write, 4096);
6328 Py_END_ALLOW_THREADS
6329 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006330 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006331
6332 return Py_BuildValue("(ii)", read, write);
6333#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006334#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006335 int fds[2];
6336 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006337 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006338 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006339 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006340 if (res != 0)
6341 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006342 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006343#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006344 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006345 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006346 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006347 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006348 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006349 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006350 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006351 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006352 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6353 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006354 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006355#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006356#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006357}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006358#endif /* HAVE_PIPE */
6359
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006360
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006361#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006362PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006363"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006364Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006365
Barry Warsaw53699e91996-12-10 23:23:01 +00006366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006367posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006368{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006369 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006370 int mode = 0666;
6371 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006372 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006373 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006374 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006375 res = mkfifo(filename, mode);
6376 Py_END_ALLOW_THREADS
6377 if (res < 0)
6378 return posix_error();
6379 Py_INCREF(Py_None);
6380 return Py_None;
6381}
6382#endif
6383
6384
Neal Norwitz11690112002-07-30 01:08:28 +00006385#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006386PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006387"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006388Create a filesystem node (file, device special file or named pipe)\n\
6389named filename. mode specifies both the permissions to use and the\n\
6390type of node to be created, being combined (bitwise OR) with one of\n\
6391S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006392device defines the newly created device special file (probably using\n\
6393os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006394
6395
6396static PyObject *
6397posix_mknod(PyObject *self, PyObject *args)
6398{
6399 char *filename;
6400 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006401 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006402 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006403 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006404 return NULL;
6405 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006406 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006407 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006408 if (res < 0)
6409 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006410 Py_INCREF(Py_None);
6411 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006412}
6413#endif
6414
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006415#ifdef HAVE_DEVICE_MACROS
6416PyDoc_STRVAR(posix_major__doc__,
6417"major(device) -> major number\n\
6418Extracts a device major number from a raw device number.");
6419
6420static PyObject *
6421posix_major(PyObject *self, PyObject *args)
6422{
6423 int device;
6424 if (!PyArg_ParseTuple(args, "i:major", &device))
6425 return NULL;
6426 return PyInt_FromLong((long)major(device));
6427}
6428
6429PyDoc_STRVAR(posix_minor__doc__,
6430"minor(device) -> minor number\n\
6431Extracts a device minor number from a raw device number.");
6432
6433static PyObject *
6434posix_minor(PyObject *self, PyObject *args)
6435{
6436 int device;
6437 if (!PyArg_ParseTuple(args, "i:minor", &device))
6438 return NULL;
6439 return PyInt_FromLong((long)minor(device));
6440}
6441
6442PyDoc_STRVAR(posix_makedev__doc__,
6443"makedev(major, minor) -> device number\n\
6444Composes a raw device number from the major and minor device numbers.");
6445
6446static PyObject *
6447posix_makedev(PyObject *self, PyObject *args)
6448{
6449 int major, minor;
6450 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6451 return NULL;
6452 return PyInt_FromLong((long)makedev(major, minor));
6453}
6454#endif /* device macros */
6455
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006456
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006457#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006458PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006459"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006460Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006461
Barry Warsaw53699e91996-12-10 23:23:01 +00006462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006463posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006464{
6465 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006466 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006467 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006468 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006469
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006470 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006471 return NULL;
6472
6473#if !defined(HAVE_LARGEFILE_SUPPORT)
6474 length = PyInt_AsLong(lenobj);
6475#else
6476 length = PyLong_Check(lenobj) ?
6477 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6478#endif
6479 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006480 return NULL;
6481
Barry Warsaw53699e91996-12-10 23:23:01 +00006482 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006483 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006484 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006485 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006486 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006487 return NULL;
6488 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006489 Py_INCREF(Py_None);
6490 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006491}
6492#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006493
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006494#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006495PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006496"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006497Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006498
Fred Drake762e2061999-08-26 17:23:54 +00006499/* Save putenv() parameters as values here, so we can collect them when they
6500 * get re-set with another call for the same key. */
6501static PyObject *posix_putenv_garbage;
6502
Tim Peters5aa91602002-01-30 05:46:57 +00006503static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006504posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006505{
6506 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006507 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006508 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006509 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006510
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006511 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006512 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006513
6514#if defined(PYOS_OS2)
6515 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6516 APIRET rc;
6517
Guido van Rossumd48f2521997-12-05 22:19:34 +00006518 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6519 if (rc != NO_ERROR)
6520 return os2_error(rc);
6521
6522 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6523 APIRET rc;
6524
Guido van Rossumd48f2521997-12-05 22:19:34 +00006525 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6526 if (rc != NO_ERROR)
6527 return os2_error(rc);
6528 } else {
6529#endif
6530
Fred Drake762e2061999-08-26 17:23:54 +00006531 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006532 len = strlen(s1) + strlen(s2) + 2;
6533 /* len includes space for a trailing \0; the size arg to
6534 PyString_FromStringAndSize does not count that */
6535 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006536 if (newstr == NULL)
6537 return PyErr_NoMemory();
Anthony Baxter64182fe2006-04-11 12:14:09 +00006538 newenv = PyString_AS_STRING(newstr);
6539 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6540 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006541 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006542 posix_error();
6543 return NULL;
6544 }
Fred Drake762e2061999-08-26 17:23:54 +00006545 /* Install the first arg and newstr in posix_putenv_garbage;
6546 * this will cause previous value to be collected. This has to
6547 * happen after the real putenv() call because the old value
6548 * was still accessible until then. */
6549 if (PyDict_SetItem(posix_putenv_garbage,
6550 PyTuple_GET_ITEM(args, 0), newstr)) {
6551 /* really not much we can do; just leak */
6552 PyErr_Clear();
6553 }
6554 else {
6555 Py_DECREF(newstr);
6556 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006557
6558#if defined(PYOS_OS2)
6559 }
6560#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006561 Py_INCREF(Py_None);
6562 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006563}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006564#endif /* putenv */
6565
Guido van Rossumc524d952001-10-19 01:31:59 +00006566#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006567PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006568"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006569Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006570
6571static PyObject *
6572posix_unsetenv(PyObject *self, PyObject *args)
6573{
6574 char *s1;
6575
6576 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6577 return NULL;
6578
6579 unsetenv(s1);
6580
6581 /* Remove the key from posix_putenv_garbage;
6582 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006583 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006584 * old value was still accessible until then.
6585 */
6586 if (PyDict_DelItem(posix_putenv_garbage,
6587 PyTuple_GET_ITEM(args, 0))) {
6588 /* really not much we can do; just leak */
6589 PyErr_Clear();
6590 }
6591
6592 Py_INCREF(Py_None);
6593 return Py_None;
6594}
6595#endif /* unsetenv */
6596
Guido van Rossumb6a47161997-09-15 22:54:34 +00006597#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006598PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006599"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006600Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006601
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006602static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006603posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006604{
6605 int code;
6606 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006607 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006608 return NULL;
6609 message = strerror(code);
6610 if (message == NULL) {
6611 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006612 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006613 return NULL;
6614 }
6615 return PyString_FromString(message);
6616}
6617#endif /* strerror */
6618
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006619
Guido van Rossumc9641791998-08-04 15:26:23 +00006620#ifdef HAVE_SYS_WAIT_H
6621
Fred Drake106c1a02002-04-23 15:58:02 +00006622#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006623PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006624"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006625Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006626
6627static PyObject *
6628posix_WCOREDUMP(PyObject *self, PyObject *args)
6629{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006630 WAIT_TYPE status;
6631 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006632
Neal Norwitzd5a37542006-03-20 06:48:34 +00006633 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006634 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006635
6636 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006637}
6638#endif /* WCOREDUMP */
6639
6640#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006641PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006642"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006643Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006644job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006645
6646static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006647posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006648{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006649 WAIT_TYPE status;
6650 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006651
Neal Norwitzd5a37542006-03-20 06:48:34 +00006652 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006653 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006654
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006655 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006656}
6657#endif /* WIFCONTINUED */
6658
Guido van Rossumc9641791998-08-04 15:26:23 +00006659#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006660PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006661"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006662Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006663
6664static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006665posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006666{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006667 WAIT_TYPE status;
6668 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006669
Neal Norwitzd5a37542006-03-20 06:48:34 +00006670 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006671 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006672
Fred Drake106c1a02002-04-23 15:58:02 +00006673 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006674}
6675#endif /* WIFSTOPPED */
6676
6677#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006678PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006679"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006680Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006681
6682static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006683posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006684{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006685 WAIT_TYPE status;
6686 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006687
Neal Norwitzd5a37542006-03-20 06:48:34 +00006688 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006689 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006690
Fred Drake106c1a02002-04-23 15:58:02 +00006691 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006692}
6693#endif /* WIFSIGNALED */
6694
6695#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006696PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006697"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006698Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006699system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006700
6701static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006702posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006703{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006704 WAIT_TYPE status;
6705 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006706
Neal Norwitzd5a37542006-03-20 06:48:34 +00006707 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006708 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006709
Fred Drake106c1a02002-04-23 15:58:02 +00006710 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006711}
6712#endif /* WIFEXITED */
6713
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006714#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006715PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006716"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006717Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006718
6719static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006720posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006721{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006722 WAIT_TYPE status;
6723 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006724
Neal Norwitzd5a37542006-03-20 06:48:34 +00006725 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006726 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006727
Guido van Rossumc9641791998-08-04 15:26:23 +00006728 return Py_BuildValue("i", WEXITSTATUS(status));
6729}
6730#endif /* WEXITSTATUS */
6731
6732#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006733PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006734"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006735Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006736value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006737
6738static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006739posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006740{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006741 WAIT_TYPE status;
6742 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006743
Neal Norwitzd5a37542006-03-20 06:48:34 +00006744 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006745 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006746
Guido van Rossumc9641791998-08-04 15:26:23 +00006747 return Py_BuildValue("i", WTERMSIG(status));
6748}
6749#endif /* WTERMSIG */
6750
6751#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006752PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006753"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006754Return the signal that stopped the process that provided\n\
6755the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006756
6757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006758posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006759{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006760 WAIT_TYPE status;
6761 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006762
Neal Norwitzd5a37542006-03-20 06:48:34 +00006763 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006764 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006765
Guido van Rossumc9641791998-08-04 15:26:23 +00006766 return Py_BuildValue("i", WSTOPSIG(status));
6767}
6768#endif /* WSTOPSIG */
6769
6770#endif /* HAVE_SYS_WAIT_H */
6771
6772
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006773#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006774#ifdef _SCO_DS
6775/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6776 needed definitions in sys/statvfs.h */
6777#define _SVID3
6778#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006779#include <sys/statvfs.h>
6780
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006781static PyObject*
6782_pystatvfs_fromstructstatvfs(struct statvfs st) {
6783 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6784 if (v == NULL)
6785 return NULL;
6786
6787#if !defined(HAVE_LARGEFILE_SUPPORT)
6788 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6789 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6790 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6791 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6792 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6793 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6794 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6795 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6796 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6797 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6798#else
6799 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6800 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006801 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006802 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006803 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006804 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006805 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006806 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006807 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006808 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006809 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006810 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006811 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006812 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006813 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6814 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6815#endif
6816
6817 return v;
6818}
6819
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006820PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006821"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006822Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006823
6824static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006825posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006826{
6827 int fd, res;
6828 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006829
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006830 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006831 return NULL;
6832 Py_BEGIN_ALLOW_THREADS
6833 res = fstatvfs(fd, &st);
6834 Py_END_ALLOW_THREADS
6835 if (res != 0)
6836 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006837
6838 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006839}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006840#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006841
6842
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006843#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006844#include <sys/statvfs.h>
6845
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006846PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006847"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006848Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006849
6850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006851posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006852{
6853 char *path;
6854 int res;
6855 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006856 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006857 return NULL;
6858 Py_BEGIN_ALLOW_THREADS
6859 res = statvfs(path, &st);
6860 Py_END_ALLOW_THREADS
6861 if (res != 0)
6862 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006863
6864 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006865}
6866#endif /* HAVE_STATVFS */
6867
6868
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006869#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006870PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006871"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006872Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006873The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006874or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006875
6876static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006877posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006878{
6879 PyObject *result = NULL;
6880 char *dir = NULL;
6881 char *pfx = NULL;
6882 char *name;
6883
6884 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6885 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006886
6887 if (PyErr_Warn(PyExc_RuntimeWarning,
6888 "tempnam is a potential security risk to your program") < 0)
6889 return NULL;
6890
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006891#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006892 name = _tempnam(dir, pfx);
6893#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006894 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006895#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006896 if (name == NULL)
6897 return PyErr_NoMemory();
6898 result = PyString_FromString(name);
6899 free(name);
6900 return result;
6901}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006902#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006903
6904
6905#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006906PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006907"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006908Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006909
6910static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006911posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006912{
6913 FILE *fp;
6914
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006915 fp = tmpfile();
6916 if (fp == NULL)
6917 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006918 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006919}
6920#endif
6921
6922
6923#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006924PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006925"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006926Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006927
6928static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006929posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006930{
6931 char buffer[L_tmpnam];
6932 char *name;
6933
Skip Montanaro95618b52001-08-18 18:52:10 +00006934 if (PyErr_Warn(PyExc_RuntimeWarning,
6935 "tmpnam is a potential security risk to your program") < 0)
6936 return NULL;
6937
Greg Wardb48bc172000-03-01 21:51:56 +00006938#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006939 name = tmpnam_r(buffer);
6940#else
6941 name = tmpnam(buffer);
6942#endif
6943 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006944 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006945#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006946 "unexpected NULL from tmpnam_r"
6947#else
6948 "unexpected NULL from tmpnam"
6949#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006950 );
6951 PyErr_SetObject(PyExc_OSError, err);
6952 Py_XDECREF(err);
6953 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006954 }
6955 return PyString_FromString(buffer);
6956}
6957#endif
6958
6959
Fred Drakec9680921999-12-13 16:37:25 +00006960/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6961 * It maps strings representing configuration variable names to
6962 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006963 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006964 * rarely-used constants. There are three separate tables that use
6965 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006966 *
6967 * This code is always included, even if none of the interfaces that
6968 * need it are included. The #if hackery needed to avoid it would be
6969 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006970 */
6971struct constdef {
6972 char *name;
6973 long value;
6974};
6975
Fred Drake12c6e2d1999-12-14 21:25:03 +00006976static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006977conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6978 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006979{
6980 if (PyInt_Check(arg)) {
6981 *valuep = PyInt_AS_LONG(arg);
6982 return 1;
6983 }
6984 if (PyString_Check(arg)) {
6985 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006986 size_t lo = 0;
6987 size_t mid;
6988 size_t hi = tablesize;
6989 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006990 char *confname = PyString_AS_STRING(arg);
6991 while (lo < hi) {
6992 mid = (lo + hi) / 2;
6993 cmp = strcmp(confname, table[mid].name);
6994 if (cmp < 0)
6995 hi = mid;
6996 else if (cmp > 0)
6997 lo = mid + 1;
6998 else {
6999 *valuep = table[mid].value;
7000 return 1;
7001 }
7002 }
7003 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7004 }
7005 else
7006 PyErr_SetString(PyExc_TypeError,
7007 "configuration names must be strings or integers");
7008 return 0;
7009}
7010
7011
7012#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7013static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007014#ifdef _PC_ABI_AIO_XFER_MAX
7015 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7016#endif
7017#ifdef _PC_ABI_ASYNC_IO
7018 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7019#endif
Fred Drakec9680921999-12-13 16:37:25 +00007020#ifdef _PC_ASYNC_IO
7021 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7022#endif
7023#ifdef _PC_CHOWN_RESTRICTED
7024 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7025#endif
7026#ifdef _PC_FILESIZEBITS
7027 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7028#endif
7029#ifdef _PC_LAST
7030 {"PC_LAST", _PC_LAST},
7031#endif
7032#ifdef _PC_LINK_MAX
7033 {"PC_LINK_MAX", _PC_LINK_MAX},
7034#endif
7035#ifdef _PC_MAX_CANON
7036 {"PC_MAX_CANON", _PC_MAX_CANON},
7037#endif
7038#ifdef _PC_MAX_INPUT
7039 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7040#endif
7041#ifdef _PC_NAME_MAX
7042 {"PC_NAME_MAX", _PC_NAME_MAX},
7043#endif
7044#ifdef _PC_NO_TRUNC
7045 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7046#endif
7047#ifdef _PC_PATH_MAX
7048 {"PC_PATH_MAX", _PC_PATH_MAX},
7049#endif
7050#ifdef _PC_PIPE_BUF
7051 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7052#endif
7053#ifdef _PC_PRIO_IO
7054 {"PC_PRIO_IO", _PC_PRIO_IO},
7055#endif
7056#ifdef _PC_SOCK_MAXBUF
7057 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7058#endif
7059#ifdef _PC_SYNC_IO
7060 {"PC_SYNC_IO", _PC_SYNC_IO},
7061#endif
7062#ifdef _PC_VDISABLE
7063 {"PC_VDISABLE", _PC_VDISABLE},
7064#endif
7065};
7066
Fred Drakec9680921999-12-13 16:37:25 +00007067static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007068conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007069{
7070 return conv_confname(arg, valuep, posix_constants_pathconf,
7071 sizeof(posix_constants_pathconf)
7072 / sizeof(struct constdef));
7073}
7074#endif
7075
7076#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007077PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007078"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007079Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007080If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007081
7082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007083posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007084{
7085 PyObject *result = NULL;
7086 int name, fd;
7087
Fred Drake12c6e2d1999-12-14 21:25:03 +00007088 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7089 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00007090 long limit;
7091
7092 errno = 0;
7093 limit = fpathconf(fd, name);
7094 if (limit == -1 && errno != 0)
7095 posix_error();
7096 else
7097 result = PyInt_FromLong(limit);
7098 }
7099 return result;
7100}
7101#endif
7102
7103
7104#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007105PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007106"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007107Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007108If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007109
7110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007111posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007112{
7113 PyObject *result = NULL;
7114 int name;
7115 char *path;
7116
7117 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7118 conv_path_confname, &name)) {
7119 long limit;
7120
7121 errno = 0;
7122 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007123 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00007124 if (errno == EINVAL)
7125 /* could be a path or name problem */
7126 posix_error();
7127 else
7128 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00007129 }
Fred Drakec9680921999-12-13 16:37:25 +00007130 else
7131 result = PyInt_FromLong(limit);
7132 }
7133 return result;
7134}
7135#endif
7136
7137#ifdef HAVE_CONFSTR
7138static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007139#ifdef _CS_ARCHITECTURE
7140 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7141#endif
7142#ifdef _CS_HOSTNAME
7143 {"CS_HOSTNAME", _CS_HOSTNAME},
7144#endif
7145#ifdef _CS_HW_PROVIDER
7146 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7147#endif
7148#ifdef _CS_HW_SERIAL
7149 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7150#endif
7151#ifdef _CS_INITTAB_NAME
7152 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7153#endif
Fred Drakec9680921999-12-13 16:37:25 +00007154#ifdef _CS_LFS64_CFLAGS
7155 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7156#endif
7157#ifdef _CS_LFS64_LDFLAGS
7158 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7159#endif
7160#ifdef _CS_LFS64_LIBS
7161 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7162#endif
7163#ifdef _CS_LFS64_LINTFLAGS
7164 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7165#endif
7166#ifdef _CS_LFS_CFLAGS
7167 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7168#endif
7169#ifdef _CS_LFS_LDFLAGS
7170 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7171#endif
7172#ifdef _CS_LFS_LIBS
7173 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7174#endif
7175#ifdef _CS_LFS_LINTFLAGS
7176 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7177#endif
Fred Draked86ed291999-12-15 15:34:33 +00007178#ifdef _CS_MACHINE
7179 {"CS_MACHINE", _CS_MACHINE},
7180#endif
Fred Drakec9680921999-12-13 16:37:25 +00007181#ifdef _CS_PATH
7182 {"CS_PATH", _CS_PATH},
7183#endif
Fred Draked86ed291999-12-15 15:34:33 +00007184#ifdef _CS_RELEASE
7185 {"CS_RELEASE", _CS_RELEASE},
7186#endif
7187#ifdef _CS_SRPC_DOMAIN
7188 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7189#endif
7190#ifdef _CS_SYSNAME
7191 {"CS_SYSNAME", _CS_SYSNAME},
7192#endif
7193#ifdef _CS_VERSION
7194 {"CS_VERSION", _CS_VERSION},
7195#endif
Fred Drakec9680921999-12-13 16:37:25 +00007196#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7197 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7198#endif
7199#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7200 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7201#endif
7202#ifdef _CS_XBS5_ILP32_OFF32_LIBS
7203 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7204#endif
7205#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7206 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7207#endif
7208#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7209 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7210#endif
7211#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7212 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7213#endif
7214#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7215 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7216#endif
7217#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7218 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7219#endif
7220#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7221 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7222#endif
7223#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7224 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7225#endif
7226#ifdef _CS_XBS5_LP64_OFF64_LIBS
7227 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7228#endif
7229#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7230 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7231#endif
7232#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7233 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7234#endif
7235#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7236 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7237#endif
7238#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7239 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7240#endif
7241#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7242 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7243#endif
Fred Draked86ed291999-12-15 15:34:33 +00007244#ifdef _MIPS_CS_AVAIL_PROCESSORS
7245 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7246#endif
7247#ifdef _MIPS_CS_BASE
7248 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7249#endif
7250#ifdef _MIPS_CS_HOSTID
7251 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7252#endif
7253#ifdef _MIPS_CS_HW_NAME
7254 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7255#endif
7256#ifdef _MIPS_CS_NUM_PROCESSORS
7257 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7258#endif
7259#ifdef _MIPS_CS_OSREL_MAJ
7260 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7261#endif
7262#ifdef _MIPS_CS_OSREL_MIN
7263 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7264#endif
7265#ifdef _MIPS_CS_OSREL_PATCH
7266 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7267#endif
7268#ifdef _MIPS_CS_OS_NAME
7269 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7270#endif
7271#ifdef _MIPS_CS_OS_PROVIDER
7272 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7273#endif
7274#ifdef _MIPS_CS_PROCESSORS
7275 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7276#endif
7277#ifdef _MIPS_CS_SERIAL
7278 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7279#endif
7280#ifdef _MIPS_CS_VENDOR
7281 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7282#endif
Fred Drakec9680921999-12-13 16:37:25 +00007283};
7284
7285static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007286conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007287{
7288 return conv_confname(arg, valuep, posix_constants_confstr,
7289 sizeof(posix_constants_confstr)
7290 / sizeof(struct constdef));
7291}
7292
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007293PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007294"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007295Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007296
7297static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007298posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007299{
7300 PyObject *result = NULL;
7301 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007302 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007303
7304 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007305 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007306
Fred Drakec9680921999-12-13 16:37:25 +00007307 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007308 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007309 if (len == 0) {
7310 if (errno) {
7311 posix_error();
7312 }
7313 else {
7314 result = Py_None;
7315 Py_INCREF(Py_None);
7316 }
Fred Drakec9680921999-12-13 16:37:25 +00007317 }
7318 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007319 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz449b24e2006-04-20 06:56:05 +00007320 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007321 if (result != NULL)
Neal Norwitz449b24e2006-04-20 06:56:05 +00007322 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007323 }
7324 else
Neal Norwitz449b24e2006-04-20 06:56:05 +00007325 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007326 }
7327 }
7328 return result;
7329}
7330#endif
7331
7332
7333#ifdef HAVE_SYSCONF
7334static struct constdef posix_constants_sysconf[] = {
7335#ifdef _SC_2_CHAR_TERM
7336 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7337#endif
7338#ifdef _SC_2_C_BIND
7339 {"SC_2_C_BIND", _SC_2_C_BIND},
7340#endif
7341#ifdef _SC_2_C_DEV
7342 {"SC_2_C_DEV", _SC_2_C_DEV},
7343#endif
7344#ifdef _SC_2_C_VERSION
7345 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7346#endif
7347#ifdef _SC_2_FORT_DEV
7348 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7349#endif
7350#ifdef _SC_2_FORT_RUN
7351 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7352#endif
7353#ifdef _SC_2_LOCALEDEF
7354 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7355#endif
7356#ifdef _SC_2_SW_DEV
7357 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7358#endif
7359#ifdef _SC_2_UPE
7360 {"SC_2_UPE", _SC_2_UPE},
7361#endif
7362#ifdef _SC_2_VERSION
7363 {"SC_2_VERSION", _SC_2_VERSION},
7364#endif
Fred Draked86ed291999-12-15 15:34:33 +00007365#ifdef _SC_ABI_ASYNCHRONOUS_IO
7366 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7367#endif
7368#ifdef _SC_ACL
7369 {"SC_ACL", _SC_ACL},
7370#endif
Fred Drakec9680921999-12-13 16:37:25 +00007371#ifdef _SC_AIO_LISTIO_MAX
7372 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7373#endif
Fred Drakec9680921999-12-13 16:37:25 +00007374#ifdef _SC_AIO_MAX
7375 {"SC_AIO_MAX", _SC_AIO_MAX},
7376#endif
7377#ifdef _SC_AIO_PRIO_DELTA_MAX
7378 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7379#endif
7380#ifdef _SC_ARG_MAX
7381 {"SC_ARG_MAX", _SC_ARG_MAX},
7382#endif
7383#ifdef _SC_ASYNCHRONOUS_IO
7384 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7385#endif
7386#ifdef _SC_ATEXIT_MAX
7387 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7388#endif
Fred Draked86ed291999-12-15 15:34:33 +00007389#ifdef _SC_AUDIT
7390 {"SC_AUDIT", _SC_AUDIT},
7391#endif
Fred Drakec9680921999-12-13 16:37:25 +00007392#ifdef _SC_AVPHYS_PAGES
7393 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7394#endif
7395#ifdef _SC_BC_BASE_MAX
7396 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7397#endif
7398#ifdef _SC_BC_DIM_MAX
7399 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7400#endif
7401#ifdef _SC_BC_SCALE_MAX
7402 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7403#endif
7404#ifdef _SC_BC_STRING_MAX
7405 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7406#endif
Fred Draked86ed291999-12-15 15:34:33 +00007407#ifdef _SC_CAP
7408 {"SC_CAP", _SC_CAP},
7409#endif
Fred Drakec9680921999-12-13 16:37:25 +00007410#ifdef _SC_CHARCLASS_NAME_MAX
7411 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7412#endif
7413#ifdef _SC_CHAR_BIT
7414 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7415#endif
7416#ifdef _SC_CHAR_MAX
7417 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7418#endif
7419#ifdef _SC_CHAR_MIN
7420 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7421#endif
7422#ifdef _SC_CHILD_MAX
7423 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7424#endif
7425#ifdef _SC_CLK_TCK
7426 {"SC_CLK_TCK", _SC_CLK_TCK},
7427#endif
7428#ifdef _SC_COHER_BLKSZ
7429 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7430#endif
7431#ifdef _SC_COLL_WEIGHTS_MAX
7432 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7433#endif
7434#ifdef _SC_DCACHE_ASSOC
7435 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7436#endif
7437#ifdef _SC_DCACHE_BLKSZ
7438 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7439#endif
7440#ifdef _SC_DCACHE_LINESZ
7441 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7442#endif
7443#ifdef _SC_DCACHE_SZ
7444 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7445#endif
7446#ifdef _SC_DCACHE_TBLKSZ
7447 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7448#endif
7449#ifdef _SC_DELAYTIMER_MAX
7450 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7451#endif
7452#ifdef _SC_EQUIV_CLASS_MAX
7453 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7454#endif
7455#ifdef _SC_EXPR_NEST_MAX
7456 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7457#endif
7458#ifdef _SC_FSYNC
7459 {"SC_FSYNC", _SC_FSYNC},
7460#endif
7461#ifdef _SC_GETGR_R_SIZE_MAX
7462 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7463#endif
7464#ifdef _SC_GETPW_R_SIZE_MAX
7465 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7466#endif
7467#ifdef _SC_ICACHE_ASSOC
7468 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7469#endif
7470#ifdef _SC_ICACHE_BLKSZ
7471 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7472#endif
7473#ifdef _SC_ICACHE_LINESZ
7474 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7475#endif
7476#ifdef _SC_ICACHE_SZ
7477 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7478#endif
Fred Draked86ed291999-12-15 15:34:33 +00007479#ifdef _SC_INF
7480 {"SC_INF", _SC_INF},
7481#endif
Fred Drakec9680921999-12-13 16:37:25 +00007482#ifdef _SC_INT_MAX
7483 {"SC_INT_MAX", _SC_INT_MAX},
7484#endif
7485#ifdef _SC_INT_MIN
7486 {"SC_INT_MIN", _SC_INT_MIN},
7487#endif
7488#ifdef _SC_IOV_MAX
7489 {"SC_IOV_MAX", _SC_IOV_MAX},
7490#endif
Fred Draked86ed291999-12-15 15:34:33 +00007491#ifdef _SC_IP_SECOPTS
7492 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7493#endif
Fred Drakec9680921999-12-13 16:37:25 +00007494#ifdef _SC_JOB_CONTROL
7495 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7496#endif
Fred Draked86ed291999-12-15 15:34:33 +00007497#ifdef _SC_KERN_POINTERS
7498 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7499#endif
7500#ifdef _SC_KERN_SIM
7501 {"SC_KERN_SIM", _SC_KERN_SIM},
7502#endif
Fred Drakec9680921999-12-13 16:37:25 +00007503#ifdef _SC_LINE_MAX
7504 {"SC_LINE_MAX", _SC_LINE_MAX},
7505#endif
7506#ifdef _SC_LOGIN_NAME_MAX
7507 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7508#endif
7509#ifdef _SC_LOGNAME_MAX
7510 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7511#endif
7512#ifdef _SC_LONG_BIT
7513 {"SC_LONG_BIT", _SC_LONG_BIT},
7514#endif
Fred Draked86ed291999-12-15 15:34:33 +00007515#ifdef _SC_MAC
7516 {"SC_MAC", _SC_MAC},
7517#endif
Fred Drakec9680921999-12-13 16:37:25 +00007518#ifdef _SC_MAPPED_FILES
7519 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7520#endif
7521#ifdef _SC_MAXPID
7522 {"SC_MAXPID", _SC_MAXPID},
7523#endif
7524#ifdef _SC_MB_LEN_MAX
7525 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7526#endif
7527#ifdef _SC_MEMLOCK
7528 {"SC_MEMLOCK", _SC_MEMLOCK},
7529#endif
7530#ifdef _SC_MEMLOCK_RANGE
7531 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7532#endif
7533#ifdef _SC_MEMORY_PROTECTION
7534 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7535#endif
7536#ifdef _SC_MESSAGE_PASSING
7537 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7538#endif
Fred Draked86ed291999-12-15 15:34:33 +00007539#ifdef _SC_MMAP_FIXED_ALIGNMENT
7540 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7541#endif
Fred Drakec9680921999-12-13 16:37:25 +00007542#ifdef _SC_MQ_OPEN_MAX
7543 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7544#endif
7545#ifdef _SC_MQ_PRIO_MAX
7546 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7547#endif
Fred Draked86ed291999-12-15 15:34:33 +00007548#ifdef _SC_NACLS_MAX
7549 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7550#endif
Fred Drakec9680921999-12-13 16:37:25 +00007551#ifdef _SC_NGROUPS_MAX
7552 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7553#endif
7554#ifdef _SC_NL_ARGMAX
7555 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7556#endif
7557#ifdef _SC_NL_LANGMAX
7558 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7559#endif
7560#ifdef _SC_NL_MSGMAX
7561 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7562#endif
7563#ifdef _SC_NL_NMAX
7564 {"SC_NL_NMAX", _SC_NL_NMAX},
7565#endif
7566#ifdef _SC_NL_SETMAX
7567 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7568#endif
7569#ifdef _SC_NL_TEXTMAX
7570 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7571#endif
7572#ifdef _SC_NPROCESSORS_CONF
7573 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7574#endif
7575#ifdef _SC_NPROCESSORS_ONLN
7576 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7577#endif
Fred Draked86ed291999-12-15 15:34:33 +00007578#ifdef _SC_NPROC_CONF
7579 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7580#endif
7581#ifdef _SC_NPROC_ONLN
7582 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7583#endif
Fred Drakec9680921999-12-13 16:37:25 +00007584#ifdef _SC_NZERO
7585 {"SC_NZERO", _SC_NZERO},
7586#endif
7587#ifdef _SC_OPEN_MAX
7588 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7589#endif
7590#ifdef _SC_PAGESIZE
7591 {"SC_PAGESIZE", _SC_PAGESIZE},
7592#endif
7593#ifdef _SC_PAGE_SIZE
7594 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7595#endif
7596#ifdef _SC_PASS_MAX
7597 {"SC_PASS_MAX", _SC_PASS_MAX},
7598#endif
7599#ifdef _SC_PHYS_PAGES
7600 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7601#endif
7602#ifdef _SC_PII
7603 {"SC_PII", _SC_PII},
7604#endif
7605#ifdef _SC_PII_INTERNET
7606 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7607#endif
7608#ifdef _SC_PII_INTERNET_DGRAM
7609 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7610#endif
7611#ifdef _SC_PII_INTERNET_STREAM
7612 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7613#endif
7614#ifdef _SC_PII_OSI
7615 {"SC_PII_OSI", _SC_PII_OSI},
7616#endif
7617#ifdef _SC_PII_OSI_CLTS
7618 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7619#endif
7620#ifdef _SC_PII_OSI_COTS
7621 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7622#endif
7623#ifdef _SC_PII_OSI_M
7624 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7625#endif
7626#ifdef _SC_PII_SOCKET
7627 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7628#endif
7629#ifdef _SC_PII_XTI
7630 {"SC_PII_XTI", _SC_PII_XTI},
7631#endif
7632#ifdef _SC_POLL
7633 {"SC_POLL", _SC_POLL},
7634#endif
7635#ifdef _SC_PRIORITIZED_IO
7636 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7637#endif
7638#ifdef _SC_PRIORITY_SCHEDULING
7639 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7640#endif
7641#ifdef _SC_REALTIME_SIGNALS
7642 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7643#endif
7644#ifdef _SC_RE_DUP_MAX
7645 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7646#endif
7647#ifdef _SC_RTSIG_MAX
7648 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7649#endif
7650#ifdef _SC_SAVED_IDS
7651 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7652#endif
7653#ifdef _SC_SCHAR_MAX
7654 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7655#endif
7656#ifdef _SC_SCHAR_MIN
7657 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7658#endif
7659#ifdef _SC_SELECT
7660 {"SC_SELECT", _SC_SELECT},
7661#endif
7662#ifdef _SC_SEMAPHORES
7663 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7664#endif
7665#ifdef _SC_SEM_NSEMS_MAX
7666 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7667#endif
7668#ifdef _SC_SEM_VALUE_MAX
7669 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7670#endif
7671#ifdef _SC_SHARED_MEMORY_OBJECTS
7672 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7673#endif
7674#ifdef _SC_SHRT_MAX
7675 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7676#endif
7677#ifdef _SC_SHRT_MIN
7678 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7679#endif
7680#ifdef _SC_SIGQUEUE_MAX
7681 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7682#endif
7683#ifdef _SC_SIGRT_MAX
7684 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7685#endif
7686#ifdef _SC_SIGRT_MIN
7687 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7688#endif
Fred Draked86ed291999-12-15 15:34:33 +00007689#ifdef _SC_SOFTPOWER
7690 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7691#endif
Fred Drakec9680921999-12-13 16:37:25 +00007692#ifdef _SC_SPLIT_CACHE
7693 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7694#endif
7695#ifdef _SC_SSIZE_MAX
7696 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7697#endif
7698#ifdef _SC_STACK_PROT
7699 {"SC_STACK_PROT", _SC_STACK_PROT},
7700#endif
7701#ifdef _SC_STREAM_MAX
7702 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7703#endif
7704#ifdef _SC_SYNCHRONIZED_IO
7705 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7706#endif
7707#ifdef _SC_THREADS
7708 {"SC_THREADS", _SC_THREADS},
7709#endif
7710#ifdef _SC_THREAD_ATTR_STACKADDR
7711 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7712#endif
7713#ifdef _SC_THREAD_ATTR_STACKSIZE
7714 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7715#endif
7716#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7717 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7718#endif
7719#ifdef _SC_THREAD_KEYS_MAX
7720 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7721#endif
7722#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7723 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7724#endif
7725#ifdef _SC_THREAD_PRIO_INHERIT
7726 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7727#endif
7728#ifdef _SC_THREAD_PRIO_PROTECT
7729 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7730#endif
7731#ifdef _SC_THREAD_PROCESS_SHARED
7732 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7733#endif
7734#ifdef _SC_THREAD_SAFE_FUNCTIONS
7735 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7736#endif
7737#ifdef _SC_THREAD_STACK_MIN
7738 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7739#endif
7740#ifdef _SC_THREAD_THREADS_MAX
7741 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7742#endif
7743#ifdef _SC_TIMERS
7744 {"SC_TIMERS", _SC_TIMERS},
7745#endif
7746#ifdef _SC_TIMER_MAX
7747 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7748#endif
7749#ifdef _SC_TTY_NAME_MAX
7750 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7751#endif
7752#ifdef _SC_TZNAME_MAX
7753 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7754#endif
7755#ifdef _SC_T_IOV_MAX
7756 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7757#endif
7758#ifdef _SC_UCHAR_MAX
7759 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7760#endif
7761#ifdef _SC_UINT_MAX
7762 {"SC_UINT_MAX", _SC_UINT_MAX},
7763#endif
7764#ifdef _SC_UIO_MAXIOV
7765 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7766#endif
7767#ifdef _SC_ULONG_MAX
7768 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7769#endif
7770#ifdef _SC_USHRT_MAX
7771 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7772#endif
7773#ifdef _SC_VERSION
7774 {"SC_VERSION", _SC_VERSION},
7775#endif
7776#ifdef _SC_WORD_BIT
7777 {"SC_WORD_BIT", _SC_WORD_BIT},
7778#endif
7779#ifdef _SC_XBS5_ILP32_OFF32
7780 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7781#endif
7782#ifdef _SC_XBS5_ILP32_OFFBIG
7783 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7784#endif
7785#ifdef _SC_XBS5_LP64_OFF64
7786 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7787#endif
7788#ifdef _SC_XBS5_LPBIG_OFFBIG
7789 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7790#endif
7791#ifdef _SC_XOPEN_CRYPT
7792 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7793#endif
7794#ifdef _SC_XOPEN_ENH_I18N
7795 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7796#endif
7797#ifdef _SC_XOPEN_LEGACY
7798 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7799#endif
7800#ifdef _SC_XOPEN_REALTIME
7801 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7802#endif
7803#ifdef _SC_XOPEN_REALTIME_THREADS
7804 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7805#endif
7806#ifdef _SC_XOPEN_SHM
7807 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7808#endif
7809#ifdef _SC_XOPEN_UNIX
7810 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7811#endif
7812#ifdef _SC_XOPEN_VERSION
7813 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7814#endif
7815#ifdef _SC_XOPEN_XCU_VERSION
7816 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7817#endif
7818#ifdef _SC_XOPEN_XPG2
7819 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7820#endif
7821#ifdef _SC_XOPEN_XPG3
7822 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7823#endif
7824#ifdef _SC_XOPEN_XPG4
7825 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7826#endif
7827};
7828
7829static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007830conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007831{
7832 return conv_confname(arg, valuep, posix_constants_sysconf,
7833 sizeof(posix_constants_sysconf)
7834 / sizeof(struct constdef));
7835}
7836
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007837PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007838"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007839Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007840
7841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007842posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007843{
7844 PyObject *result = NULL;
7845 int name;
7846
7847 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7848 int value;
7849
7850 errno = 0;
7851 value = sysconf(name);
7852 if (value == -1 && errno != 0)
7853 posix_error();
7854 else
7855 result = PyInt_FromLong(value);
7856 }
7857 return result;
7858}
7859#endif
7860
7861
Fred Drakebec628d1999-12-15 18:31:10 +00007862/* This code is used to ensure that the tables of configuration value names
7863 * are in sorted order as required by conv_confname(), and also to build the
7864 * the exported dictionaries that are used to publish information about the
7865 * names available on the host platform.
7866 *
7867 * Sorting the table at runtime ensures that the table is properly ordered
7868 * when used, even for platforms we're not able to test on. It also makes
7869 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007870 */
Fred Drakebec628d1999-12-15 18:31:10 +00007871
7872static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007873cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007874{
7875 const struct constdef *c1 =
7876 (const struct constdef *) v1;
7877 const struct constdef *c2 =
7878 (const struct constdef *) v2;
7879
7880 return strcmp(c1->name, c2->name);
7881}
7882
7883static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007884setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007885 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007886{
Fred Drakebec628d1999-12-15 18:31:10 +00007887 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007888 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007889
7890 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7891 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007892 if (d == NULL)
7893 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007894
Barry Warsaw3155db32000-04-13 15:20:40 +00007895 for (i=0; i < tablesize; ++i) {
7896 PyObject *o = PyInt_FromLong(table[i].value);
7897 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7898 Py_XDECREF(o);
7899 Py_DECREF(d);
7900 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007901 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007902 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007903 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007904 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007905}
7906
Fred Drakebec628d1999-12-15 18:31:10 +00007907/* Return -1 on failure, 0 on success. */
7908static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007909setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007910{
7911#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007912 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007913 sizeof(posix_constants_pathconf)
7914 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007915 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007916 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007917#endif
7918#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007919 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007920 sizeof(posix_constants_confstr)
7921 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007922 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007923 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007924#endif
7925#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007926 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007927 sizeof(posix_constants_sysconf)
7928 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007929 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007930 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007931#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007932 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007933}
Fred Draked86ed291999-12-15 15:34:33 +00007934
7935
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007936PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007937"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007938Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007939in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007940
7941static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007942posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007943{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007944 abort();
7945 /*NOTREACHED*/
7946 Py_FatalError("abort() called from Python code didn't abort!");
7947 return NULL;
7948}
Fred Drakebec628d1999-12-15 18:31:10 +00007949
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007950#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007951PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007952"startfile(filepath [, operation]) - Start a file with its associated\n\
7953application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007954\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007955When \"operation\" is not specified or \"open\", this acts like\n\
7956double-clicking the file in Explorer, or giving the file name as an\n\
7957argument to the DOS \"start\" command: the file is opened with whatever\n\
7958application (if any) its extension is associated.\n\
7959When another \"operation\" is given, it specifies what should be done with\n\
7960the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007961\n\
7962startfile returns as soon as the associated application is launched.\n\
7963There is no option to wait for the application to close, and no way\n\
7964to retrieve the application's exit status.\n\
7965\n\
7966The filepath is relative to the current directory. If you want to use\n\
7967an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007968the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007969
7970static PyObject *
7971win32_startfile(PyObject *self, PyObject *args)
7972{
7973 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007974 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007975 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00007976#ifdef Py_WIN_WIDE_FILENAMES
7977 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007978 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00007979 if (!PyArg_ParseTuple(args, "U|s:startfile",
7980 &unipath, &operation)) {
7981 PyErr_Clear();
7982 goto normal;
7983 }
7984
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007985
7986 if (operation) {
7987 woperation = PyUnicode_DecodeASCII(operation,
7988 strlen(operation), NULL);
7989 if (!woperation) {
7990 PyErr_Clear();
7991 operation = NULL;
7992 goto normal;
7993 }
Georg Brandlad89dc82006-04-03 12:26:26 +00007994 }
7995
7996 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007997 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00007998 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00007999 NULL, NULL, SW_SHOWNORMAL);
8000 Py_END_ALLOW_THREADS
8001
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00008002 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00008003 if (rc <= (HINSTANCE)32) {
8004 PyObject *errval = win32_error_unicode("startfile",
8005 PyUnicode_AS_UNICODE(unipath));
8006 return errval;
8007 }
8008 Py_INCREF(Py_None);
8009 return Py_None;
8010 }
8011#endif
8012
8013normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00008014 if (!PyArg_ParseTuple(args, "et|s:startfile",
8015 Py_FileSystemDefaultEncoding, &filepath,
8016 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00008017 return NULL;
8018 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00008019 rc = ShellExecute((HWND)0, operation, filepath,
8020 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008021 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00008022 if (rc <= (HINSTANCE)32) {
8023 PyObject *errval = win32_error("startfile", filepath);
8024 PyMem_Free(filepath);
8025 return errval;
8026 }
8027 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00008028 Py_INCREF(Py_None);
8029 return Py_None;
8030}
8031#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008032
Martin v. Löwis438b5342002-12-27 10:16:42 +00008033#ifdef HAVE_GETLOADAVG
8034PyDoc_STRVAR(posix_getloadavg__doc__,
8035"getloadavg() -> (float, float, float)\n\n\
8036Return the number of processes in the system run queue averaged over\n\
8037the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8038was unobtainable");
8039
8040static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008041posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008042{
8043 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008044 if (getloadavg(loadavg, 3)!=3) {
8045 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8046 return NULL;
8047 } else
8048 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8049}
8050#endif
8051
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008052#ifdef MS_WINDOWS
8053
8054PyDoc_STRVAR(win32_urandom__doc__,
8055"urandom(n) -> str\n\n\
8056Return a string of n random bytes suitable for cryptographic use.");
8057
8058typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8059 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8060 DWORD dwFlags );
8061typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8062 BYTE *pbBuffer );
8063
8064static CRYPTGENRANDOM pCryptGenRandom = NULL;
8065static HCRYPTPROV hCryptProv = 0;
8066
Tim Peters4ad82172004-08-30 17:02:04 +00008067static PyObject*
8068win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008069{
Tim Petersd3115382004-08-30 17:36:46 +00008070 int howMany;
8071 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008072
Tim Peters4ad82172004-08-30 17:02:04 +00008073 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00008074 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00008075 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00008076 if (howMany < 0)
8077 return PyErr_Format(PyExc_ValueError,
8078 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008079
Tim Peters4ad82172004-08-30 17:02:04 +00008080 if (hCryptProv == 0) {
8081 HINSTANCE hAdvAPI32 = NULL;
8082 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008083
Tim Peters4ad82172004-08-30 17:02:04 +00008084 /* Obtain handle to the DLL containing CryptoAPI
8085 This should not fail */
8086 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8087 if(hAdvAPI32 == NULL)
8088 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008089
Tim Peters4ad82172004-08-30 17:02:04 +00008090 /* Obtain pointers to the CryptoAPI functions
8091 This will fail on some early versions of Win95 */
8092 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8093 hAdvAPI32,
8094 "CryptAcquireContextA");
8095 if (pCryptAcquireContext == NULL)
8096 return PyErr_Format(PyExc_NotImplementedError,
8097 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008098
Tim Peters4ad82172004-08-30 17:02:04 +00008099 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8100 hAdvAPI32, "CryptGenRandom");
Georg Brandl74bb7832006-09-06 06:03:59 +00008101 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00008102 return PyErr_Format(PyExc_NotImplementedError,
8103 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008104
Tim Peters4ad82172004-08-30 17:02:04 +00008105 /* Acquire context */
8106 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8107 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8108 return win32_error("CryptAcquireContext", NULL);
8109 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008110
Tim Peters4ad82172004-08-30 17:02:04 +00008111 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00008112 result = PyString_FromStringAndSize(NULL, howMany);
8113 if (result != NULL) {
8114 /* Get random data */
8115 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
8116 PyString_AS_STRING(result))) {
8117 Py_DECREF(result);
8118 return win32_error("CryptGenRandom", NULL);
8119 }
Tim Peters4ad82172004-08-30 17:02:04 +00008120 }
Tim Petersd3115382004-08-30 17:36:46 +00008121 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008122}
8123#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008124
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008125#ifdef __VMS
8126/* Use openssl random routine */
8127#include <openssl/rand.h>
8128PyDoc_STRVAR(vms_urandom__doc__,
8129"urandom(n) -> str\n\n\
8130Return a string of n random bytes suitable for cryptographic use.");
8131
8132static PyObject*
8133vms_urandom(PyObject *self, PyObject *args)
8134{
8135 int howMany;
8136 PyObject* result;
8137
8138 /* Read arguments */
8139 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8140 return NULL;
8141 if (howMany < 0)
8142 return PyErr_Format(PyExc_ValueError,
8143 "negative argument not allowed");
8144
8145 /* Allocate bytes */
8146 result = PyString_FromStringAndSize(NULL, howMany);
8147 if (result != NULL) {
8148 /* Get random data */
8149 if (RAND_pseudo_bytes((unsigned char*)
8150 PyString_AS_STRING(result),
8151 howMany) < 0) {
8152 Py_DECREF(result);
8153 return PyErr_Format(PyExc_ValueError,
8154 "RAND_pseudo_bytes");
8155 }
8156 }
8157 return result;
8158}
8159#endif
8160
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008161static PyMethodDef posix_methods[] = {
8162 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8163#ifdef HAVE_TTYNAME
8164 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8165#endif
8166 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008167#ifdef HAVE_CHFLAGS
8168 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8169#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008170 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008171#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008172 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008173#endif /* HAVE_CHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008174#ifdef HAVE_LCHFLAGS
8175 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8176#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008177#ifdef HAVE_LCHOWN
8178 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8179#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008180#ifdef HAVE_CHROOT
8181 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8182#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008183#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00008184 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008185#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008186#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00008187 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008188#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00008189 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008190#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008191#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008192#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008193 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008194#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008195 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8196 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8197 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008198#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008199 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008200#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008201#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008202 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008203#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008204 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8205 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8206 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008207 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008208#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008209 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008210#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008211#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008212 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008213#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008214 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008215#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00008216 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008217#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008218 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8219 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8220 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008221#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00008222 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008223#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008224 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008225#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008226 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8227 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008228#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008229#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008230 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8231 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008232#if defined(PYOS_OS2)
8233 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8234 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8235#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008236#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008237#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008238 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008239#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008240#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008241 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008242#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008243#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008244 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008245#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008246#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008247 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008248#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008249#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008250 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008251#endif /* HAVE_GETEGID */
8252#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008253 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008254#endif /* HAVE_GETEUID */
8255#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008256 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008257#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008258#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008259 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008260#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008261 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008262#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008263 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008264#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008265#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008266 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008267#endif /* HAVE_GETPPID */
8268#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008269 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008270#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008271#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008272 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008273#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008274#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008275 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008276#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008277#ifdef HAVE_KILLPG
8278 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8279#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008280#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008281 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008282#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008283#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008284 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008285#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008286 {"popen2", win32_popen2, METH_VARARGS},
8287 {"popen3", win32_popen3, METH_VARARGS},
8288 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008289 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008290#else
8291#if defined(PYOS_OS2) && defined(PYCC_GCC)
8292 {"popen2", os2emx_popen2, METH_VARARGS},
8293 {"popen3", os2emx_popen3, METH_VARARGS},
8294 {"popen4", os2emx_popen4, METH_VARARGS},
8295#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008296#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008297#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008298#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008299 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008300#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008301#ifdef HAVE_SETEUID
8302 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8303#endif /* HAVE_SETEUID */
8304#ifdef HAVE_SETEGID
8305 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8306#endif /* HAVE_SETEGID */
8307#ifdef HAVE_SETREUID
8308 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8309#endif /* HAVE_SETREUID */
8310#ifdef HAVE_SETREGID
8311 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8312#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008313#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008314 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008315#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008316#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008317 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008318#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008319#ifdef HAVE_GETPGID
8320 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8321#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008322#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008323 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008324#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008325#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008326 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008327#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008328#ifdef HAVE_WAIT3
8329 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8330#endif /* HAVE_WAIT3 */
8331#ifdef HAVE_WAIT4
8332 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8333#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008334#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008335 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008336#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008337#ifdef HAVE_GETSID
8338 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8339#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008340#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008341 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008342#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008343#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008344 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008345#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008346#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008347 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008348#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008349#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008350 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008351#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008352 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8353 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8354 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8355 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8356 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8357 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8358 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8359 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8360 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008361 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008362#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008363 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008364#endif
8365#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008366 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008367#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008368#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008369 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8370#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008371#ifdef HAVE_DEVICE_MACROS
8372 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8373 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8374 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8375#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008376#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008377 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008378#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008379#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008380 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008381#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008382#ifdef HAVE_UNSETENV
8383 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8384#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00008385#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008386 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00008387#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00008388#ifdef HAVE_FCHDIR
8389 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8390#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008391#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008392 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008393#endif
8394#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008395 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008396#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008397#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008398#ifdef WCOREDUMP
8399 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8400#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008401#ifdef WIFCONTINUED
8402 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8403#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008404#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008405 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008406#endif /* WIFSTOPPED */
8407#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008408 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008409#endif /* WIFSIGNALED */
8410#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008411 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008412#endif /* WIFEXITED */
8413#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008414 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008415#endif /* WEXITSTATUS */
8416#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008417 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008418#endif /* WTERMSIG */
8419#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008420 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008421#endif /* WSTOPSIG */
8422#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008423#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008424 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008425#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008426#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008427 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008428#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008429#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008430 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008431#endif
8432#ifdef HAVE_TEMPNAM
8433 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8434#endif
8435#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008436 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008437#endif
Fred Drakec9680921999-12-13 16:37:25 +00008438#ifdef HAVE_CONFSTR
8439 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8440#endif
8441#ifdef HAVE_SYSCONF
8442 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8443#endif
8444#ifdef HAVE_FPATHCONF
8445 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8446#endif
8447#ifdef HAVE_PATHCONF
8448 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8449#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008450 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008451#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008452 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8453#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008454#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008455 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008456#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008457 #ifdef MS_WINDOWS
8458 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8459 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008460 #ifdef __VMS
8461 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8462 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008463 {NULL, NULL} /* Sentinel */
8464};
8465
8466
Barry Warsaw4a342091996-12-19 23:50:02 +00008467static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008468ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008469{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008470 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008471}
8472
Guido van Rossumd48f2521997-12-05 22:19:34 +00008473#if defined(PYOS_OS2)
8474/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008475static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008476{
8477 APIRET rc;
8478 ULONG values[QSV_MAX+1];
8479 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008480 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008481
8482 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008483 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008484 Py_END_ALLOW_THREADS
8485
8486 if (rc != NO_ERROR) {
8487 os2_error(rc);
8488 return -1;
8489 }
8490
Fred Drake4d1e64b2002-04-15 19:40:07 +00008491 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8492 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8493 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8494 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8495 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8496 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8497 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008498
8499 switch (values[QSV_VERSION_MINOR]) {
8500 case 0: ver = "2.00"; break;
8501 case 10: ver = "2.10"; break;
8502 case 11: ver = "2.11"; break;
8503 case 30: ver = "3.00"; break;
8504 case 40: ver = "4.00"; break;
8505 case 50: ver = "5.00"; break;
8506 default:
Tim Peters885d4572001-11-28 20:27:42 +00008507 PyOS_snprintf(tmp, sizeof(tmp),
8508 "%d-%d", values[QSV_VERSION_MAJOR],
8509 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008510 ver = &tmp[0];
8511 }
8512
8513 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008514 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008515 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008516
8517 /* Add Indicator of Which Drive was Used to Boot the System */
8518 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8519 tmp[1] = ':';
8520 tmp[2] = '\0';
8521
Fred Drake4d1e64b2002-04-15 19:40:07 +00008522 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008523}
8524#endif
8525
Barry Warsaw4a342091996-12-19 23:50:02 +00008526static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008527all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008528{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008529#ifdef F_OK
8530 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008531#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008532#ifdef R_OK
8533 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008534#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008535#ifdef W_OK
8536 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008537#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008538#ifdef X_OK
8539 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008540#endif
Fred Drakec9680921999-12-13 16:37:25 +00008541#ifdef NGROUPS_MAX
8542 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8543#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008544#ifdef TMP_MAX
8545 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8546#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008547#ifdef WCONTINUED
8548 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8549#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008550#ifdef WNOHANG
8551 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008552#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008553#ifdef WUNTRACED
8554 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8555#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008556#ifdef O_RDONLY
8557 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8558#endif
8559#ifdef O_WRONLY
8560 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8561#endif
8562#ifdef O_RDWR
8563 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8564#endif
8565#ifdef O_NDELAY
8566 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8567#endif
8568#ifdef O_NONBLOCK
8569 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8570#endif
8571#ifdef O_APPEND
8572 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8573#endif
8574#ifdef O_DSYNC
8575 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8576#endif
8577#ifdef O_RSYNC
8578 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8579#endif
8580#ifdef O_SYNC
8581 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8582#endif
8583#ifdef O_NOCTTY
8584 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8585#endif
8586#ifdef O_CREAT
8587 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8588#endif
8589#ifdef O_EXCL
8590 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8591#endif
8592#ifdef O_TRUNC
8593 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8594#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008595#ifdef O_BINARY
8596 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8597#endif
8598#ifdef O_TEXT
8599 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8600#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008601#ifdef O_LARGEFILE
8602 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8603#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008604#ifdef O_SHLOCK
8605 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8606#endif
8607#ifdef O_EXLOCK
8608 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8609#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008610
Tim Peters5aa91602002-01-30 05:46:57 +00008611/* MS Windows */
8612#ifdef O_NOINHERIT
8613 /* Don't inherit in child processes. */
8614 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8615#endif
8616#ifdef _O_SHORT_LIVED
8617 /* Optimize for short life (keep in memory). */
8618 /* MS forgot to define this one with a non-underscore form too. */
8619 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8620#endif
8621#ifdef O_TEMPORARY
8622 /* Automatically delete when last handle is closed. */
8623 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8624#endif
8625#ifdef O_RANDOM
8626 /* Optimize for random access. */
8627 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8628#endif
8629#ifdef O_SEQUENTIAL
8630 /* Optimize for sequential access. */
8631 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8632#endif
8633
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008634/* GNU extensions. */
8635#ifdef O_DIRECT
8636 /* Direct disk access. */
8637 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8638#endif
8639#ifdef O_DIRECTORY
8640 /* Must be a directory. */
8641 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8642#endif
8643#ifdef O_NOFOLLOW
8644 /* Do not follow links. */
8645 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8646#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008647
Barry Warsaw5676bd12003-01-07 20:57:09 +00008648 /* These come from sysexits.h */
8649#ifdef EX_OK
8650 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008651#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008652#ifdef EX_USAGE
8653 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008654#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008655#ifdef EX_DATAERR
8656 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008657#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008658#ifdef EX_NOINPUT
8659 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008660#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008661#ifdef EX_NOUSER
8662 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008663#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008664#ifdef EX_NOHOST
8665 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008666#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008667#ifdef EX_UNAVAILABLE
8668 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008669#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008670#ifdef EX_SOFTWARE
8671 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008672#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008673#ifdef EX_OSERR
8674 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008675#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008676#ifdef EX_OSFILE
8677 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008678#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008679#ifdef EX_CANTCREAT
8680 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008681#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008682#ifdef EX_IOERR
8683 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008684#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008685#ifdef EX_TEMPFAIL
8686 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008687#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008688#ifdef EX_PROTOCOL
8689 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008690#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008691#ifdef EX_NOPERM
8692 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008693#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008694#ifdef EX_CONFIG
8695 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008696#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008697#ifdef EX_NOTFOUND
8698 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008699#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008700
Guido van Rossum246bc171999-02-01 23:54:31 +00008701#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008702#if defined(PYOS_OS2) && defined(PYCC_GCC)
8703 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8704 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8705 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8706 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8707 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8708 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8709 if (ins(d, "P_PM", (long)P_PM)) return -1;
8710 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8711 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8712 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8713 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8714 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8715 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8716 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8717 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8718 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8719 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8720 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8721 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8722 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8723#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008724 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8725 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8726 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8727 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8728 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008729#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008730#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008731
Guido van Rossumd48f2521997-12-05 22:19:34 +00008732#if defined(PYOS_OS2)
8733 if (insertvalues(d)) return -1;
8734#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008735 return 0;
8736}
8737
8738
Tim Peters5aa91602002-01-30 05:46:57 +00008739#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008740#define INITFUNC initnt
8741#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008742
8743#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008744#define INITFUNC initos2
8745#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008746
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008747#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008748#define INITFUNC initposix
8749#define MODNAME "posix"
8750#endif
8751
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008752PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008753INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008754{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008755 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008756
Fred Drake4d1e64b2002-04-15 19:40:07 +00008757 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008758 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008759 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008760 if (m == NULL)
8761 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008762
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008763 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008764 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008765 Py_XINCREF(v);
8766 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008767 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008768 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008769
Fred Drake4d1e64b2002-04-15 19:40:07 +00008770 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008771 return;
8772
Fred Drake4d1e64b2002-04-15 19:40:07 +00008773 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008774 return;
8775
Fred Drake4d1e64b2002-04-15 19:40:07 +00008776 Py_INCREF(PyExc_OSError);
8777 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008778
Guido van Rossumb3d39562000-01-31 18:41:26 +00008779#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008780 if (posix_putenv_garbage == NULL)
8781 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008782#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008783
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008784 if (!initialized) {
8785 stat_result_desc.name = MODNAME ".stat_result";
8786 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8787 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8788 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8789 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8790 structseq_new = StatResultType.tp_new;
8791 StatResultType.tp_new = statresult_new;
8792
8793 statvfs_result_desc.name = MODNAME ".statvfs_result";
8794 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8795 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008796 Py_INCREF((PyObject*) &StatResultType);
8797 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008798 Py_INCREF((PyObject*) &StatVFSResultType);
8799 PyModule_AddObject(m, "statvfs_result",
8800 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008801 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00008802
8803#ifdef __APPLE__
8804 /*
8805 * Step 2 of weak-linking support on Mac OS X.
8806 *
8807 * The code below removes functions that are not available on the
8808 * currently active platform.
8809 *
8810 * This block allow one to use a python binary that was build on
8811 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8812 * OSX 10.4.
8813 */
8814#ifdef HAVE_FSTATVFS
8815 if (fstatvfs == NULL) {
8816 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8817 return;
8818 }
8819 }
8820#endif /* HAVE_FSTATVFS */
8821
8822#ifdef HAVE_STATVFS
8823 if (statvfs == NULL) {
8824 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8825 return;
8826 }
8827 }
8828#endif /* HAVE_STATVFS */
8829
8830# ifdef HAVE_LCHOWN
8831 if (lchown == NULL) {
8832 if (PyObject_DelAttrString(m, "lchown") == -1) {
8833 return;
8834 }
8835 }
8836#endif /* HAVE_LCHOWN */
8837
8838
8839#endif /* __APPLE__ */
8840
Guido van Rossumb6775db1994-08-01 11:34:53 +00008841}
Anthony Baxterac6bd462006-04-13 02:06:09 +00008842
8843#ifdef __cplusplus
8844}
8845#endif
8846
Martin v. Löwis18aaa562006-10-15 08:43:33 +00008847