blob: a2068ac0af0797566d3d92cd55c09fa3201b7c08 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Thomas Wouters477c8d52006-05-27 19:21:47 +000016#ifdef __APPLE__
17 /*
18 * Step 1 of support for weak-linking a number of symbols existing on
19 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
31#include "structseq.h"
32
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#if defined(PYOS_OS2)
49#define INCL_DOS
50#define INCL_DOSERRORS
51#define INCL_DOSPROCESS
52#define INCL_NOPMAPI
53#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000054#if defined(PYCC_GCC)
55#include <ctype.h>
56#include <io.h>
57#include <stdio.h>
58#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000059#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000060#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000061#endif
62
Thomas Wouters0e3f5912006-08-11 14:57:12 +000063#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000064#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065#endif /* HAVE_SYS_TYPES_H */
66
67#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000069#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070
Guido van Rossum36bc6801995-06-14 22:54:23 +000071#ifdef HAVE_SYS_WAIT_H
72#include <sys/wait.h> /* For WNOHANG */
73#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000074
Thomas Wouters0e3f5912006-08-11 14:57:12 +000075#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000076#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000078
Guido van Rossumb6775db1994-08-01 11:34:53 +000079#ifdef HAVE_FCNTL_H
80#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000081#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000082
Guido van Rossuma6535fd2001-10-18 19:44:10 +000083#ifdef HAVE_GRP_H
84#include <grp.h>
85#endif
86
Barry Warsaw5676bd12003-01-07 20:57:09 +000087#ifdef HAVE_SYSEXITS_H
88#include <sysexits.h>
89#endif /* HAVE_SYSEXITS_H */
90
Anthony Baxter8a560de2004-10-13 15:30:56 +000091#ifdef HAVE_SYS_LOADAVG_H
92#include <sys/loadavg.h>
93#endif
94
Guido van Rossuma4916fa1996-05-23 22:58:55 +000095/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000096/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000097#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000098#include <process.h>
99#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000100#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000101#define HAVE_GETCWD 1
102#define HAVE_OPENDIR 1
103#define HAVE_SYSTEM 1
104#if defined(__OS2__)
105#define HAVE_EXECV 1
106#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000107#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#include <process.h>
109#else
110#ifdef __BORLANDC__ /* Borland compiler */
111#define HAVE_EXECV 1
112#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000113#define HAVE_OPENDIR 1
114#define HAVE_PIPE 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000115#define HAVE_SYSTEM 1
116#define HAVE_WAIT 1
117#else
118#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000119#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000120#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000121#define HAVE_EXECV 1
122#define HAVE_PIPE 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000123#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000124#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000125#define HAVE_FSYNC 1
126#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000127#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000128#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
129/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000130#else /* all other compilers */
131/* Unix functions that the configure script doesn't check for */
132#define HAVE_EXECV 1
133#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000134#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
135#define HAVE_FORK1 1
136#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137#define HAVE_GETCWD 1
138#define HAVE_GETEGID 1
139#define HAVE_GETEUID 1
140#define HAVE_GETGID 1
141#define HAVE_GETPPID 1
142#define HAVE_GETUID 1
143#define HAVE_KILL 1
144#define HAVE_OPENDIR 1
145#define HAVE_PIPE 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#define HAVE_SYSTEM 1
147#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000148#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000149#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#endif /* _MSC_VER */
151#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000152#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000153#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000154
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000156
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000157#if defined(__sgi)&&_COMPILER_VERSION>=700
158/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
159 (default) */
160extern char *ctermid_r(char *);
161#endif
162
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000163#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000164#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000165extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000166#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000167#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000168extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000169#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000170extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000171#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000172#endif
173#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int chdir(char *);
175extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000176#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000177extern int chdir(const char *);
178extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000179#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000180#ifdef __BORLANDC__
181extern int chmod(const char *, int);
182#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000183extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000184#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000185extern int chown(const char *, uid_t, gid_t);
186extern char *getcwd(char *, int);
187extern char *strerror(int);
188extern int link(const char *, const char *);
189extern int rename(const char *, const char *);
190extern int stat(const char *, struct stat *);
191extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000193extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000194#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000196extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000197#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000199
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000200#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000201
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_UTIME_H
203#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000204#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000206#ifdef HAVE_SYS_UTIME_H
207#include <sys/utime.h>
208#define HAVE_UTIME_H /* pretend we do for the rest of this file */
209#endif /* HAVE_SYS_UTIME_H */
210
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#ifdef HAVE_SYS_TIMES_H
212#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000213#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214
215#ifdef HAVE_SYS_PARAM_H
216#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000217#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218
219#ifdef HAVE_SYS_UTSNAME_H
220#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000221#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000223#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000225#define NAMLEN(dirent) strlen((dirent)->d_name)
226#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000227#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#include <direct.h>
229#define NAMLEN(dirent) strlen((dirent)->d_name)
230#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000232#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000233#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000234#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000236#endif
237#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000239#endif
240#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#endif
243#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000245#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000246#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000248#endif
249#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000250#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000251#endif
252#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000254#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000255#include "osdefs.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000257#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000258#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259
Guido van Rossumd48f2521997-12-05 22:19:34 +0000260#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000262#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000263
Tim Petersbc2e10e2002-03-03 23:17:02 +0000264#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000265#if defined(PATH_MAX) && PATH_MAX > 1024
266#define MAXPATHLEN PATH_MAX
267#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000268#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000269#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000270#endif /* MAXPATHLEN */
271
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000272#ifdef UNION_WAIT
273/* Emulate some macros on systems that have a union instead of macros */
274
275#ifndef WIFEXITED
276#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
277#endif
278
279#ifndef WEXITSTATUS
280#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
281#endif
282
283#ifndef WTERMSIG
284#define WTERMSIG(u_wait) ((u_wait).w_termsig)
285#endif
286
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000287#define WAIT_TYPE union wait
288#define WAIT_STATUS_INT(s) (s.w_status)
289
290#else /* !UNION_WAIT */
291#define WAIT_TYPE int
292#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000293#endif /* UNION_WAIT */
294
Greg Wardb48bc172000-03-01 21:51:56 +0000295/* Don't use the "_r" form if we don't need it (also, won't have a
296 prototype for it, at least on Solaris -- maybe others as well?). */
297#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
298#define USE_CTERMID_R
299#endif
300
301#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
302#define USE_TMPNAM_R
303#endif
304
Fred Drake699f3522000-06-29 21:12:41 +0000305/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000306#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000307#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000308# define STAT win32_stat
309# define FSTAT win32_fstat
310# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000311#else
312# define STAT stat
313# define FSTAT fstat
314# define STRUCT_STAT struct stat
315#endif
316
Tim Peters11b23062003-04-23 02:39:17 +0000317#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000318#include <sys/mkdev.h>
319#else
320#if defined(MAJOR_IN_SYSMACROS)
321#include <sys/sysmacros.h>
322#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000323#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
324#include <sys/mkdev.h>
325#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000326#endif
Fred Drake699f3522000-06-29 21:12:41 +0000327
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000328/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000329#ifdef WITH_NEXT_FRAMEWORK
330/* On Darwin/MacOSX a shared library or framework has no access to
331** environ directly, we must obtain it with _NSGetEnviron().
332*/
333#include <crt_externs.h>
334static char **environ;
335#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000336extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000337#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338
Barry Warsaw53699e91996-12-10 23:23:01 +0000339static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000340convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341{
Barry Warsaw53699e91996-12-10 23:23:01 +0000342 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000343 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000344 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345 if (d == NULL)
346 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000347#ifdef WITH_NEXT_FRAMEWORK
348 if (environ == NULL)
349 environ = *_NSGetEnviron();
350#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000351 if (environ == NULL)
352 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000353 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000355 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000356 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357 char *p = strchr(*e, '=');
358 if (p == NULL)
359 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000360 k = PyString_FromStringAndSize(*e, (int)(p-*e));
361 if (k == NULL) {
362 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000363 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000364 }
365 v = PyString_FromString(p+1);
366 if (v == NULL) {
367 PyErr_Clear();
368 Py_DECREF(k);
369 continue;
370 }
371 if (PyDict_GetItem(d, k) == NULL) {
372 if (PyDict_SetItem(d, k, v) != 0)
373 PyErr_Clear();
374 }
375 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000376 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000377 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000378#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000379 {
380 APIRET rc;
381 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
382
383 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000384 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000385 PyObject *v = PyString_FromString(buffer);
386 PyDict_SetItemString(d, "BEGINLIBPATH", v);
387 Py_DECREF(v);
388 }
389 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
390 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
391 PyObject *v = PyString_FromString(buffer);
392 PyDict_SetItemString(d, "ENDLIBPATH", v);
393 Py_DECREF(v);
394 }
395 }
396#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000397 return d;
398}
399
400
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000401/* Set a POSIX-specific error from errno, and return NULL */
402
Barry Warsawd58d7641998-07-23 16:14:40 +0000403static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000404posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000405{
Barry Warsawca74da41999-02-09 19:31:45 +0000406 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000407}
Barry Warsawd58d7641998-07-23 16:14:40 +0000408static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000409posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000410{
Barry Warsawca74da41999-02-09 19:31:45 +0000411 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000412}
413
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000414#ifdef Py_WIN_WIDE_FILENAMES
415static PyObject *
416posix_error_with_unicode_filename(Py_UNICODE* name)
417{
418 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
419}
420#endif /* Py_WIN_WIDE_FILENAMES */
421
422
Mark Hammondef8b6542001-05-13 08:04:26 +0000423static PyObject *
424posix_error_with_allocated_filename(char* name)
425{
426 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
427 PyMem_Free(name);
428 return rc;
429}
430
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000431#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000432static PyObject *
433win32_error(char* function, char* filename)
434{
Mark Hammond33a6da92000-08-15 00:46:38 +0000435 /* XXX We should pass the function name along in the future.
436 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000437 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000438 Windows error object, which is non-trivial.
439 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000440 errno = GetLastError();
441 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000442 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000443 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000444 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000445}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000446
447#ifdef Py_WIN_WIDE_FILENAMES
448static PyObject *
449win32_error_unicode(char* function, Py_UNICODE* filename)
450{
451 /* XXX - see win32_error for comments on 'function' */
452 errno = GetLastError();
453 if (filename)
454 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
455 else
456 return PyErr_SetFromWindowsErr(errno);
457}
458
459static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
460{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000461}
462
463/* Function suitable for O& conversion */
464static int
465convert_to_unicode(PyObject *arg, void* _param)
466{
467 PyObject **param = (PyObject**)_param;
468 if (PyUnicode_CheckExact(arg)) {
469 Py_INCREF(arg);
470 *param = arg;
471 }
472 else if (PyUnicode_Check(arg)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000473 /* For a Unicode subtype that's not a Unicode object,
474 return a true Unicode object with the same data. */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000475 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
476 PyUnicode_GET_SIZE(arg));
477 return *param != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000478 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000479 else
480 *param = PyUnicode_FromEncodedObject(arg,
481 Py_FileSystemDefaultEncoding,
482 "strict");
483 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000484}
485
486#endif /* Py_WIN_WIDE_FILENAMES */
487
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000488#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000489
Guido van Rossumd48f2521997-12-05 22:19:34 +0000490#if defined(PYOS_OS2)
491/**********************************************************************
492 * Helper Function to Trim and Format OS/2 Messages
493 **********************************************************************/
494 static void
495os2_formatmsg(char *msgbuf, int msglen, char *reason)
496{
497 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
498
499 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
500 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
501
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000502 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000503 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
504 }
505
506 /* Add Optional Reason Text */
507 if (reason) {
508 strcat(msgbuf, " : ");
509 strcat(msgbuf, reason);
510 }
511}
512
513/**********************************************************************
514 * Decode an OS/2 Operating System Error Code
515 *
516 * A convenience function to lookup an OS/2 error code and return a
517 * text message we can use to raise a Python exception.
518 *
519 * Notes:
520 * The messages for errors returned from the OS/2 kernel reside in
521 * the file OSO001.MSG in the \OS2 directory hierarchy.
522 *
523 **********************************************************************/
524 static char *
525os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
526{
527 APIRET rc;
528 ULONG msglen;
529
530 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
531 Py_BEGIN_ALLOW_THREADS
532 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
533 errorcode, "oso001.msg", &msglen);
534 Py_END_ALLOW_THREADS
535
536 if (rc == NO_ERROR)
537 os2_formatmsg(msgbuf, msglen, reason);
538 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000539 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000540 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000541
542 return msgbuf;
543}
544
545/* Set an OS/2-specific error and return NULL. OS/2 kernel
546 errors are not in a global variable e.g. 'errno' nor are
547 they congruent with posix error numbers. */
548
549static PyObject * os2_error(int code)
550{
551 char text[1024];
552 PyObject *v;
553
554 os2_strerror(text, sizeof(text), code, "");
555
556 v = Py_BuildValue("(is)", code, text);
557 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000558 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000559 Py_DECREF(v);
560 }
561 return NULL; /* Signal to Python that an Exception is Pending */
562}
563
564#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000565
566/* POSIX generic methods */
567
Barry Warsaw53699e91996-12-10 23:23:01 +0000568static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000569posix_fildes(PyObject *fdobj, int (*func)(int))
570{
571 int fd;
572 int res;
573 fd = PyObject_AsFileDescriptor(fdobj);
574 if (fd < 0)
575 return NULL;
576 Py_BEGIN_ALLOW_THREADS
577 res = (*func)(fd);
578 Py_END_ALLOW_THREADS
579 if (res < 0)
580 return posix_error();
581 Py_INCREF(Py_None);
582 return Py_None;
583}
Guido van Rossum21142a01999-01-08 21:05:37 +0000584
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000585#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000586static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000587unicode_file_names(void)
588{
589 static int canusewide = -1;
590 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000591 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000592 the Windows NT family. */
593 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
594 }
595 return canusewide;
596}
597#endif
Tim Peters11b23062003-04-23 02:39:17 +0000598
Guido van Rossum21142a01999-01-08 21:05:37 +0000599static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000600posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000601{
Mark Hammondef8b6542001-05-13 08:04:26 +0000602 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000603 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000604 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000605 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000606 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000607 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000608 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000609 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000610 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000611 return posix_error_with_allocated_filename(path1);
612 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000613 Py_INCREF(Py_None);
614 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000615}
616
Barry Warsaw53699e91996-12-10 23:23:01 +0000617static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000618posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000619 char *format,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000620 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000621{
Mark Hammondef8b6542001-05-13 08:04:26 +0000622 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000623 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000624 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000625 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000626 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000627 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000628 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000629 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000630 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000631 PyMem_Free(path1);
632 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000633 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000634 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000635 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000636 Py_INCREF(Py_None);
637 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000638}
639
Thomas Wouters477c8d52006-05-27 19:21:47 +0000640#ifdef Py_WIN_WIDE_FILENAMES
641static PyObject*
642win32_1str(PyObject* args, char* func,
643 char* format, BOOL (__stdcall *funcA)(LPCSTR),
644 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
645{
646 PyObject *uni;
647 char *ansi;
648 BOOL result;
649 if (unicode_file_names()) {
650 if (!PyArg_ParseTuple(args, wformat, &uni))
651 PyErr_Clear();
652 else {
653 Py_BEGIN_ALLOW_THREADS
654 result = funcW(PyUnicode_AsUnicode(uni));
655 Py_END_ALLOW_THREADS
656 if (!result)
657 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
658 Py_INCREF(Py_None);
659 return Py_None;
660 }
661 }
662 if (!PyArg_ParseTuple(args, format, &ansi))
663 return NULL;
664 Py_BEGIN_ALLOW_THREADS
665 result = funcA(ansi);
666 Py_END_ALLOW_THREADS
667 if (!result)
668 return win32_error(func, ansi);
669 Py_INCREF(Py_None);
670 return Py_None;
671
672}
673
674/* This is a reimplementation of the C library's chdir function,
675 but one that produces Win32 errors instead of DOS error codes.
676 chdir is essentially a wrapper around SetCurrentDirectory; however,
677 it also needs to set "magic" environment variables indicating
678 the per-drive current directory, which are of the form =<drive>: */
679BOOL __stdcall
680win32_chdir(LPCSTR path)
681{
682 char new_path[MAX_PATH+1];
683 int result;
684 char env[4] = "=x:";
685
686 if(!SetCurrentDirectoryA(path))
687 return FALSE;
688 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
689 if (!result)
690 return FALSE;
691 /* In the ANSI API, there should not be any paths longer
692 than MAX_PATH. */
693 assert(result <= MAX_PATH+1);
694 if (strncmp(new_path, "\\\\", 2) == 0 ||
695 strncmp(new_path, "//", 2) == 0)
696 /* UNC path, nothing to do. */
697 return TRUE;
698 env[1] = new_path[0];
699 return SetEnvironmentVariableA(env, new_path);
700}
701
702/* The Unicode version differs from the ANSI version
703 since the current directory might exceed MAX_PATH characters */
704BOOL __stdcall
705win32_wchdir(LPCWSTR path)
706{
707 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
708 int result;
709 wchar_t env[4] = L"=x:";
710
711 if(!SetCurrentDirectoryW(path))
712 return FALSE;
713 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
714 if (!result)
715 return FALSE;
716 if (result > MAX_PATH+1) {
717 new_path = malloc(result);
718 if (!new_path) {
719 SetLastError(ERROR_OUTOFMEMORY);
720 return FALSE;
721 }
722 }
723 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
724 wcsncmp(new_path, L"//", 2) == 0)
725 /* UNC path, nothing to do. */
726 return TRUE;
727 env[1] = new_path[0];
728 result = SetEnvironmentVariableW(env, new_path);
729 if (new_path != _new_path)
730 free(new_path);
731 return result;
732}
733#endif
734
Martin v. Löwis14694662006-02-03 12:54:16 +0000735#ifdef MS_WINDOWS
736/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
737 - time stamps are restricted to second resolution
738 - file modification times suffer from forth-and-back conversions between
739 UTC and local time
740 Therefore, we implement our own stat, based on the Win32 API directly.
741*/
742#define HAVE_STAT_NSEC 1
743
744struct win32_stat{
745 int st_dev;
746 __int64 st_ino;
747 unsigned short st_mode;
748 int st_nlink;
749 int st_uid;
750 int st_gid;
751 int st_rdev;
752 __int64 st_size;
753 int st_atime;
754 int st_atime_nsec;
755 int st_mtime;
756 int st_mtime_nsec;
757 int st_ctime;
758 int st_ctime_nsec;
759};
760
761static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
762
763static void
764FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
765{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000766 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
767 /* Cannot simply cast and dereference in_ptr,
768 since it might not be aligned properly */
769 __int64 in;
770 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000771 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
772 /* XXX Win32 supports time stamps past 2038; we currently don't */
773 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
774}
775
Thomas Wouters477c8d52006-05-27 19:21:47 +0000776static void
777time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
778{
779 /* XXX endianness */
780 __int64 out;
781 out = time_in + secs_between_epochs;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000782 out = out * 10000000 + nsec_in / 100;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000783 memcpy(out_ptr, &out, sizeof(out));
784}
785
Martin v. Löwis14694662006-02-03 12:54:16 +0000786/* Below, we *know* that ugo+r is 0444 */
787#if _S_IREAD != 0400
788#error Unsupported C library
789#endif
790static int
791attributes_to_mode(DWORD attr)
792{
793 int m = 0;
794 if (attr & FILE_ATTRIBUTE_DIRECTORY)
795 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
796 else
797 m |= _S_IFREG;
798 if (attr & FILE_ATTRIBUTE_READONLY)
799 m |= 0444;
800 else
801 m |= 0666;
802 return m;
803}
804
805static int
806attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
807{
808 memset(result, 0, sizeof(*result));
809 result->st_mode = attributes_to_mode(info->dwFileAttributes);
810 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
811 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
812 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
813 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
814
815 return 0;
816}
817
Thomas Wouters89f507f2006-12-13 04:49:30 +0000818/* Emulate GetFileAttributesEx[AW] on Windows 95 */
819static int checked = 0;
820static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
821static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
822static void
823check_gfax()
824{
825 HINSTANCE hKernel32;
826 if (checked)
827 return;
828 checked = 1;
829 hKernel32 = GetModuleHandle("KERNEL32");
830 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
831 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
832}
833
Guido van Rossumd8faa362007-04-27 19:54:29 +0000834static BOOL
835attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
836{
837 HANDLE hFindFile;
838 WIN32_FIND_DATAA FileData;
839 hFindFile = FindFirstFileA(pszFile, &FileData);
840 if (hFindFile == INVALID_HANDLE_VALUE)
841 return FALSE;
842 FindClose(hFindFile);
843 pfad->dwFileAttributes = FileData.dwFileAttributes;
844 pfad->ftCreationTime = FileData.ftCreationTime;
845 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
846 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
847 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
848 pfad->nFileSizeLow = FileData.nFileSizeLow;
849 return TRUE;
850}
851
852static BOOL
853attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
854{
855 HANDLE hFindFile;
856 WIN32_FIND_DATAW FileData;
857 hFindFile = FindFirstFileW(pszFile, &FileData);
858 if (hFindFile == INVALID_HANDLE_VALUE)
859 return FALSE;
860 FindClose(hFindFile);
861 pfad->dwFileAttributes = FileData.dwFileAttributes;
862 pfad->ftCreationTime = FileData.ftCreationTime;
863 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
864 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
865 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
866 pfad->nFileSizeLow = FileData.nFileSizeLow;
867 return TRUE;
868}
869
Thomas Wouters89f507f2006-12-13 04:49:30 +0000870static BOOL WINAPI
871Py_GetFileAttributesExA(LPCSTR pszFile,
872 GET_FILEEX_INFO_LEVELS level,
873 LPVOID pv)
874{
875 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000876 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
877 /* First try to use the system's implementation, if that is
878 available and either succeeds to gives an error other than
879 that it isn't implemented. */
880 check_gfax();
881 if (gfaxa) {
882 result = gfaxa(pszFile, level, pv);
883 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
884 return result;
885 }
886 /* It's either not present, or not implemented.
887 Emulate using FindFirstFile. */
888 if (level != GetFileExInfoStandard) {
889 SetLastError(ERROR_INVALID_PARAMETER);
890 return FALSE;
891 }
892 /* Use GetFileAttributes to validate that the file name
893 does not contain wildcards (which FindFirstFile would
894 accept). */
895 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
896 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000897 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000898}
899
900static BOOL WINAPI
901Py_GetFileAttributesExW(LPCWSTR pszFile,
902 GET_FILEEX_INFO_LEVELS level,
903 LPVOID pv)
904{
905 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000906 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
907 /* First try to use the system's implementation, if that is
908 available and either succeeds to gives an error other than
909 that it isn't implemented. */
910 check_gfax();
911 if (gfaxa) {
912 result = gfaxw(pszFile, level, pv);
913 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
914 return result;
915 }
916 /* It's either not present, or not implemented.
917 Emulate using FindFirstFile. */
918 if (level != GetFileExInfoStandard) {
919 SetLastError(ERROR_INVALID_PARAMETER);
920 return FALSE;
921 }
922 /* Use GetFileAttributes to validate that the file name
923 does not contain wildcards (which FindFirstFile would
924 accept). */
925 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
926 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000927 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000928}
929
Martin v. Löwis14694662006-02-03 12:54:16 +0000930static int
931win32_stat(const char* path, struct win32_stat *result)
932{
933 WIN32_FILE_ATTRIBUTE_DATA info;
934 int code;
935 char *dot;
936 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +0000937 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +0000938 if (GetLastError() != ERROR_SHARING_VIOLATION) {
939 /* Protocol violation: we explicitly clear errno, instead of
940 setting it to a POSIX error. Callers should use GetLastError. */
941 errno = 0;
942 return -1;
943 } else {
944 /* Could not get attributes on open file. Fall back to
945 reading the directory. */
946 if (!attributes_from_dir(path, &info)) {
947 /* Very strange. This should not fail now */
948 errno = 0;
949 return -1;
950 }
951 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000952 }
953 code = attribute_data_to_stat(&info, result);
954 if (code != 0)
955 return code;
956 /* Set S_IFEXEC if it is an .exe, .bat, ... */
957 dot = strrchr(path, '.');
958 if (dot) {
959 if (stricmp(dot, ".bat") == 0 ||
960 stricmp(dot, ".cmd") == 0 ||
961 stricmp(dot, ".exe") == 0 ||
962 stricmp(dot, ".com") == 0)
963 result->st_mode |= 0111;
964 }
965 return code;
966}
967
968static int
969win32_wstat(const wchar_t* path, struct win32_stat *result)
970{
971 int code;
972 const wchar_t *dot;
973 WIN32_FILE_ATTRIBUTE_DATA info;
974 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +0000975 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +0000976 if (GetLastError() != ERROR_SHARING_VIOLATION) {
977 /* Protocol violation: we explicitly clear errno, instead of
978 setting it to a POSIX error. Callers should use GetLastError. */
979 errno = 0;
980 return -1;
981 } else {
982 /* Could not get attributes on open file. Fall back to
983 reading the directory. */
984 if (!attributes_from_dir_w(path, &info)) {
985 /* Very strange. This should not fail now */
986 errno = 0;
987 return -1;
988 }
989 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000990 }
991 code = attribute_data_to_stat(&info, result);
992 if (code < 0)
993 return code;
994 /* Set IFEXEC if it is an .exe, .bat, ... */
995 dot = wcsrchr(path, '.');
996 if (dot) {
997 if (_wcsicmp(dot, L".bat") == 0 ||
998 _wcsicmp(dot, L".cmd") == 0 ||
999 _wcsicmp(dot, L".exe") == 0 ||
1000 _wcsicmp(dot, L".com") == 0)
1001 result->st_mode |= 0111;
1002 }
1003 return code;
1004}
1005
1006static int
1007win32_fstat(int file_number, struct win32_stat *result)
1008{
1009 BY_HANDLE_FILE_INFORMATION info;
1010 HANDLE h;
1011 int type;
1012
1013 h = (HANDLE)_get_osfhandle(file_number);
1014
1015 /* Protocol violation: we explicitly clear errno, instead of
1016 setting it to a POSIX error. Callers should use GetLastError. */
1017 errno = 0;
1018
1019 if (h == INVALID_HANDLE_VALUE) {
1020 /* This is really a C library error (invalid file handle).
1021 We set the Win32 error to the closes one matching. */
1022 SetLastError(ERROR_INVALID_HANDLE);
1023 return -1;
1024 }
1025 memset(result, 0, sizeof(*result));
1026
1027 type = GetFileType(h);
1028 if (type == FILE_TYPE_UNKNOWN) {
1029 DWORD error = GetLastError();
1030 if (error != 0) {
1031 return -1;
1032 }
1033 /* else: valid but unknown file */
1034 }
1035
1036 if (type != FILE_TYPE_DISK) {
1037 if (type == FILE_TYPE_CHAR)
1038 result->st_mode = _S_IFCHR;
1039 else if (type == FILE_TYPE_PIPE)
1040 result->st_mode = _S_IFIFO;
1041 return 0;
1042 }
1043
1044 if (!GetFileInformationByHandle(h, &info)) {
1045 return -1;
1046 }
1047
1048 /* similar to stat() */
1049 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1050 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1051 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1052 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1053 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1054 /* specific to fstat() */
1055 result->st_nlink = info.nNumberOfLinks;
1056 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1057 return 0;
1058}
1059
1060#endif /* MS_WINDOWS */
1061
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001062PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001063"stat_result: Result from stat or lstat.\n\n\
1064This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001065 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001066or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1067\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001068Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1069or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001070\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001071See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001072
1073static PyStructSequence_Field stat_result_fields[] = {
1074 {"st_mode", "protection bits"},
1075 {"st_ino", "inode"},
1076 {"st_dev", "device"},
1077 {"st_nlink", "number of hard links"},
1078 {"st_uid", "user ID of owner"},
1079 {"st_gid", "group ID of owner"},
1080 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001081 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1082 {NULL, "integer time of last access"},
1083 {NULL, "integer time of last modification"},
1084 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001085 {"st_atime", "time of last access"},
1086 {"st_mtime", "time of last modification"},
1087 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001088#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001089 {"st_blksize", "blocksize for filesystem I/O"},
1090#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001091#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001092 {"st_blocks", "number of blocks allocated"},
1093#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001094#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001095 {"st_rdev", "device type (if inode device)"},
1096#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001097#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1098 {"st_flags", "user defined flags for file"},
1099#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001100#ifdef HAVE_STRUCT_STAT_ST_GEN
1101 {"st_gen", "generation number"},
1102#endif
1103#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1104 {"st_birthtime", "time of creation"},
1105#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001106 {0}
1107};
1108
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001109#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001110#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001111#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001112#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001113#endif
1114
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001115#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001116#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1117#else
1118#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1119#endif
1120
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001121#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001122#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1123#else
1124#define ST_RDEV_IDX ST_BLOCKS_IDX
1125#endif
1126
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001127#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1128#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1129#else
1130#define ST_FLAGS_IDX ST_RDEV_IDX
1131#endif
1132
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001133#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001134#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001135#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001136#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001137#endif
1138
1139#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1140#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1141#else
1142#define ST_BIRTHTIME_IDX ST_GEN_IDX
1143#endif
1144
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001145static PyStructSequence_Desc stat_result_desc = {
1146 "stat_result", /* name */
1147 stat_result__doc__, /* doc */
1148 stat_result_fields,
1149 10
1150};
1151
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001152PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001153"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1154This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001155 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001156or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001157\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001158See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001159
1160static PyStructSequence_Field statvfs_result_fields[] = {
1161 {"f_bsize", },
1162 {"f_frsize", },
1163 {"f_blocks", },
1164 {"f_bfree", },
1165 {"f_bavail", },
1166 {"f_files", },
1167 {"f_ffree", },
1168 {"f_favail", },
1169 {"f_flag", },
1170 {"f_namemax",},
1171 {0}
1172};
1173
1174static PyStructSequence_Desc statvfs_result_desc = {
1175 "statvfs_result", /* name */
1176 statvfs_result__doc__, /* doc */
1177 statvfs_result_fields,
1178 10
1179};
1180
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001181static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001182static PyTypeObject StatResultType;
1183static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001184static newfunc structseq_new;
1185
1186static PyObject *
1187statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1188{
1189 PyStructSequence *result;
1190 int i;
1191
1192 result = (PyStructSequence*)structseq_new(type, args, kwds);
1193 if (!result)
1194 return NULL;
1195 /* If we have been initialized from a tuple,
1196 st_?time might be set to None. Initialize it
1197 from the int slots. */
1198 for (i = 7; i <= 9; i++) {
1199 if (result->ob_item[i+3] == Py_None) {
1200 Py_DECREF(Py_None);
1201 Py_INCREF(result->ob_item[i]);
1202 result->ob_item[i+3] = result->ob_item[i];
1203 }
1204 }
1205 return (PyObject*)result;
1206}
1207
1208
1209
1210/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001211static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001212
1213PyDoc_STRVAR(stat_float_times__doc__,
1214"stat_float_times([newval]) -> oldval\n\n\
1215Determine whether os.[lf]stat represents time stamps as float objects.\n\
1216If newval is True, future calls to stat() return floats, if it is False,\n\
1217future calls return ints. \n\
1218If newval is omitted, return the current setting.\n");
1219
1220static PyObject*
1221stat_float_times(PyObject* self, PyObject *args)
1222{
1223 int newval = -1;
1224 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1225 return NULL;
1226 if (newval == -1)
1227 /* Return old value */
1228 return PyBool_FromLong(_stat_float_times);
1229 _stat_float_times = newval;
1230 Py_INCREF(Py_None);
1231 return Py_None;
1232}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001233
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001234static void
1235fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1236{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001237 PyObject *fval,*ival;
1238#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001239 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001240#else
1241 ival = PyInt_FromLong((long)sec);
1242#endif
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001243 if (!ival)
1244 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001245 if (_stat_float_times) {
1246 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1247 } else {
1248 fval = ival;
1249 Py_INCREF(fval);
1250 }
1251 PyStructSequence_SET_ITEM(v, index, ival);
1252 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001253}
1254
Tim Peters5aa91602002-01-30 05:46:57 +00001255/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001256 (used by posix_stat() and posix_fstat()) */
1257static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001258_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001259{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001260 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001261 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001262 if (v == NULL)
1263 return NULL;
1264
Martin v. Löwis14694662006-02-03 12:54:16 +00001265 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001266#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001267 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001268 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001269#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001270 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001271#endif
1272#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001273 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001274 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001275#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001276 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001277#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001278 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1279 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1280 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001281#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001282 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001283 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001284#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001285 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001286#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001287
Martin v. Löwis14694662006-02-03 12:54:16 +00001288#if defined(HAVE_STAT_TV_NSEC)
1289 ansec = st->st_atim.tv_nsec;
1290 mnsec = st->st_mtim.tv_nsec;
1291 cnsec = st->st_ctim.tv_nsec;
1292#elif defined(HAVE_STAT_TV_NSEC2)
1293 ansec = st->st_atimespec.tv_nsec;
1294 mnsec = st->st_mtimespec.tv_nsec;
1295 cnsec = st->st_ctimespec.tv_nsec;
1296#elif defined(HAVE_STAT_NSEC)
1297 ansec = st->st_atime_nsec;
1298 mnsec = st->st_mtime_nsec;
1299 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001300#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001301 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001302#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001303 fill_time(v, 7, st->st_atime, ansec);
1304 fill_time(v, 8, st->st_mtime, mnsec);
1305 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001306
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001307#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001308 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001309 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001310#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001311#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001312 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001313 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001314#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001315#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001316 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001317 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001318#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001319#ifdef HAVE_STRUCT_STAT_ST_GEN
1320 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001321 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001322#endif
1323#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1324 {
1325 PyObject *val;
1326 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001327 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001328#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001329 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001330#else
1331 bnsec = 0;
1332#endif
1333 if (_stat_float_times) {
1334 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1335 } else {
1336 val = PyInt_FromLong((long)bsec);
1337 }
1338 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1339 val);
1340 }
1341#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001342#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1343 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001344 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001345#endif
Fred Drake699f3522000-06-29 21:12:41 +00001346
1347 if (PyErr_Occurred()) {
1348 Py_DECREF(v);
1349 return NULL;
1350 }
1351
1352 return v;
1353}
1354
Martin v. Löwisd8948722004-06-02 09:57:56 +00001355#ifdef MS_WINDOWS
1356
1357/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1358 where / can be used in place of \ and the trailing slash is optional.
1359 Both SERVER and SHARE must have at least one character.
1360*/
1361
1362#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1363#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001364#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001365#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001366#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001367
Tim Peters4ad82172004-08-30 17:02:04 +00001368static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001369IsUNCRootA(char *path, int pathlen)
1370{
1371 #define ISSLASH ISSLASHA
1372
1373 int i, share;
1374
1375 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1376 /* minimum UNCRoot is \\x\y */
1377 return FALSE;
1378 for (i = 2; i < pathlen ; i++)
1379 if (ISSLASH(path[i])) break;
1380 if (i == 2 || i == pathlen)
1381 /* do not allow \\\SHARE or \\SERVER */
1382 return FALSE;
1383 share = i+1;
1384 for (i = share; i < pathlen; i++)
1385 if (ISSLASH(path[i])) break;
1386 return (i != share && (i == pathlen || i == pathlen-1));
1387
1388 #undef ISSLASH
1389}
1390
1391#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001392static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001393IsUNCRootW(Py_UNICODE *path, int pathlen)
1394{
1395 #define ISSLASH ISSLASHW
1396
1397 int i, share;
1398
1399 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1400 /* minimum UNCRoot is \\x\y */
1401 return FALSE;
1402 for (i = 2; i < pathlen ; i++)
1403 if (ISSLASH(path[i])) break;
1404 if (i == 2 || i == pathlen)
1405 /* do not allow \\\SHARE or \\SERVER */
1406 return FALSE;
1407 share = i+1;
1408 for (i = share; i < pathlen; i++)
1409 if (ISSLASH(path[i])) break;
1410 return (i != share && (i == pathlen || i == pathlen-1));
1411
1412 #undef ISSLASH
1413}
1414#endif /* Py_WIN_WIDE_FILENAMES */
1415#endif /* MS_WINDOWS */
1416
Barry Warsaw53699e91996-12-10 23:23:01 +00001417static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001418posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001419 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001420#ifdef __VMS
1421 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1422#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001423 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001424#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001425 char *wformat,
1426 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001427{
Fred Drake699f3522000-06-29 21:12:41 +00001428 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001429 char *path = NULL; /* pass this to stat; do not free() it */
1430 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001431 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001432 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001433
1434#ifdef Py_WIN_WIDE_FILENAMES
1435 /* If on wide-character-capable OS see if argument
1436 is Unicode and if so use wide API. */
1437 if (unicode_file_names()) {
1438 PyUnicodeObject *po;
1439 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001440 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1441
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001442 Py_BEGIN_ALLOW_THREADS
1443 /* PyUnicode_AS_UNICODE result OK without
1444 thread lock as it is a simple dereference. */
1445 res = wstatfunc(wpath, &st);
1446 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001447
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001448 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001449 return win32_error_unicode("stat", wpath);
1450 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001451 }
1452 /* Drop the argument parsing error as narrow strings
1453 are also valid. */
1454 PyErr_Clear();
1455 }
1456#endif
1457
Tim Peters5aa91602002-01-30 05:46:57 +00001458 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001459 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001460 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001461 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001462
Barry Warsaw53699e91996-12-10 23:23:01 +00001463 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001464 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001465 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001466
1467 if (res != 0) {
1468#ifdef MS_WINDOWS
1469 result = win32_error("stat", pathfree);
1470#else
1471 result = posix_error_with_filename(pathfree);
1472#endif
1473 }
1474 else
1475 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001476
Tim Peters500bd032001-12-19 19:05:01 +00001477 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001478 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001479}
1480
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001481/* POSIX methods */
1482
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001483PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001484"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001485Use the real uid/gid to test for access to a path. Note that most\n\
1486operations will use the effective uid/gid, therefore this routine can\n\
1487be used in a suid/sgid environment to test if the invoking user has the\n\
1488specified access to the path. The mode argument can be F_OK to test\n\
1489existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001490
1491static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001492posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001493{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001494 char *path;
1495 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001496
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001497#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001498 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001499 if (unicode_file_names()) {
1500 PyUnicodeObject *po;
1501 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1502 Py_BEGIN_ALLOW_THREADS
1503 /* PyUnicode_AS_UNICODE OK without thread lock as
1504 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001505 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001506 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001507 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001508 }
1509 /* Drop the argument parsing error as narrow strings
1510 are also valid. */
1511 PyErr_Clear();
1512 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001513 if (!PyArg_ParseTuple(args, "eti:access",
1514 Py_FileSystemDefaultEncoding, &path, &mode))
1515 return 0;
1516 Py_BEGIN_ALLOW_THREADS
1517 attr = GetFileAttributesA(path);
1518 Py_END_ALLOW_THREADS
1519 PyMem_Free(path);
1520finish:
1521 if (attr == 0xFFFFFFFF)
1522 /* File does not exist, or cannot read attributes */
1523 return PyBool_FromLong(0);
1524 /* Access is possible if either write access wasn't requested, or
1525 the file isn't read-only. */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001526 return PyBool_FromLong(!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001527#else
1528 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001529 if (!PyArg_ParseTuple(args, "eti:access",
1530 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001531 return NULL;
1532 Py_BEGIN_ALLOW_THREADS
1533 res = access(path, mode);
1534 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001535 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001536 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001537#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001538}
1539
Guido van Rossumd371ff11999-01-25 16:12:23 +00001540#ifndef F_OK
1541#define F_OK 0
1542#endif
1543#ifndef R_OK
1544#define R_OK 4
1545#endif
1546#ifndef W_OK
1547#define W_OK 2
1548#endif
1549#ifndef X_OK
1550#define X_OK 1
1551#endif
1552
1553#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001554PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001555"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001556Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001557
1558static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001559posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001560{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001561 int id;
1562 char *ret;
1563
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001564 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001565 return NULL;
1566
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001567#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001568 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001569 if (id == 0) {
1570 ret = ttyname();
1571 }
1572 else {
1573 ret = NULL;
1574 }
1575#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001576 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001577#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001578 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001579 return posix_error();
1580 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001581}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001582#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001583
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001584#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001585PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001586"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001587Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001588
1589static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001590posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001591{
1592 char *ret;
1593 char buffer[L_ctermid];
1594
Greg Wardb48bc172000-03-01 21:51:56 +00001595#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001596 ret = ctermid_r(buffer);
1597#else
1598 ret = ctermid(buffer);
1599#endif
1600 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001601 return posix_error();
1602 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001603}
1604#endif
1605
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001606PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001607"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001608Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001609
Barry Warsaw53699e91996-12-10 23:23:01 +00001610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001611posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001612{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001613#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001614 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001615#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001616 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001617#elif defined(__VMS)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001618 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001619#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001620 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001621#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001622}
1623
Fred Drake4d1e64b2002-04-15 19:40:07 +00001624#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001625PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001626"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001627Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001628opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001629
1630static PyObject *
1631posix_fchdir(PyObject *self, PyObject *fdobj)
1632{
1633 return posix_fildes(fdobj, fchdir);
1634}
1635#endif /* HAVE_FCHDIR */
1636
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001637
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001638PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001639"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001640Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001641
Barry Warsaw53699e91996-12-10 23:23:01 +00001642static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001643posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001644{
Mark Hammondef8b6542001-05-13 08:04:26 +00001645 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001646 int i;
1647 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001648#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001649 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001650 if (unicode_file_names()) {
1651 PyUnicodeObject *po;
1652 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1653 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001654 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1655 if (attr != 0xFFFFFFFF) {
1656 if (i & _S_IWRITE)
1657 attr &= ~FILE_ATTRIBUTE_READONLY;
1658 else
1659 attr |= FILE_ATTRIBUTE_READONLY;
1660 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1661 }
1662 else
1663 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001664 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001665 if (!res)
1666 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001667 PyUnicode_AS_UNICODE(po));
1668 Py_INCREF(Py_None);
1669 return Py_None;
1670 }
1671 /* Drop the argument parsing error as narrow strings
1672 are also valid. */
1673 PyErr_Clear();
1674 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001675 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1676 &path, &i))
1677 return NULL;
1678 Py_BEGIN_ALLOW_THREADS
1679 attr = GetFileAttributesA(path);
1680 if (attr != 0xFFFFFFFF) {
1681 if (i & _S_IWRITE)
1682 attr &= ~FILE_ATTRIBUTE_READONLY;
1683 else
1684 attr |= FILE_ATTRIBUTE_READONLY;
1685 res = SetFileAttributesA(path, attr);
1686 }
1687 else
1688 res = 0;
1689 Py_END_ALLOW_THREADS
1690 if (!res) {
1691 win32_error("chmod", path);
1692 PyMem_Free(path);
1693 return NULL;
1694 }
1695 PyMem_Free(path);
1696 Py_INCREF(Py_None);
1697 return Py_None;
1698#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001699 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001700 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001701 return NULL;
1702 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001703 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001704 Py_END_ALLOW_THREADS
1705 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001706 return posix_error_with_allocated_filename(path);
1707 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001708 Py_INCREF(Py_None);
1709 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001710#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001711}
1712
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001713
Thomas Wouterscf297e42007-02-23 15:07:44 +00001714#ifdef HAVE_CHFLAGS
1715PyDoc_STRVAR(posix_chflags__doc__,
1716"chflags(path, flags)\n\n\
1717Set file flags.");
1718
1719static PyObject *
1720posix_chflags(PyObject *self, PyObject *args)
1721{
1722 char *path;
1723 unsigned long flags;
1724 int res;
1725 if (!PyArg_ParseTuple(args, "etk:chflags",
1726 Py_FileSystemDefaultEncoding, &path, &flags))
1727 return NULL;
1728 Py_BEGIN_ALLOW_THREADS
1729 res = chflags(path, flags);
1730 Py_END_ALLOW_THREADS
1731 if (res < 0)
1732 return posix_error_with_allocated_filename(path);
1733 PyMem_Free(path);
1734 Py_INCREF(Py_None);
1735 return Py_None;
1736}
1737#endif /* HAVE_CHFLAGS */
1738
1739#ifdef HAVE_LCHFLAGS
1740PyDoc_STRVAR(posix_lchflags__doc__,
1741"lchflags(path, flags)\n\n\
1742Set file flags.\n\
1743This function will not follow symbolic links.");
1744
1745static PyObject *
1746posix_lchflags(PyObject *self, PyObject *args)
1747{
1748 char *path;
1749 unsigned long flags;
1750 int res;
1751 if (!PyArg_ParseTuple(args, "etk:lchflags",
1752 Py_FileSystemDefaultEncoding, &path, &flags))
1753 return NULL;
1754 Py_BEGIN_ALLOW_THREADS
1755 res = lchflags(path, flags);
1756 Py_END_ALLOW_THREADS
1757 if (res < 0)
1758 return posix_error_with_allocated_filename(path);
1759 PyMem_Free(path);
1760 Py_INCREF(Py_None);
1761 return Py_None;
1762}
1763#endif /* HAVE_LCHFLAGS */
1764
Martin v. Löwis244edc82001-10-04 22:44:26 +00001765#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001766PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001767"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001768Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001769
1770static PyObject *
1771posix_chroot(PyObject *self, PyObject *args)
1772{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001773 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001774}
1775#endif
1776
Guido van Rossum21142a01999-01-08 21:05:37 +00001777#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001778PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001779"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001780force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001781
1782static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001783posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001784{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001785 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001786}
1787#endif /* HAVE_FSYNC */
1788
1789#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001790
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001791#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001792extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1793#endif
1794
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001795PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001796"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001797force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001798 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001799
1800static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001801posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001802{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001803 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001804}
1805#endif /* HAVE_FDATASYNC */
1806
1807
Fredrik Lundh10723342000-07-10 16:38:09 +00001808#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001809PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001810"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001811Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001812
Barry Warsaw53699e91996-12-10 23:23:01 +00001813static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001814posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001815{
Mark Hammondef8b6542001-05-13 08:04:26 +00001816 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001817 int uid, gid;
1818 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001819 if (!PyArg_ParseTuple(args, "etii:chown",
1820 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001821 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001822 return NULL;
1823 Py_BEGIN_ALLOW_THREADS
1824 res = chown(path, (uid_t) uid, (gid_t) gid);
1825 Py_END_ALLOW_THREADS
1826 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001827 return posix_error_with_allocated_filename(path);
1828 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001829 Py_INCREF(Py_None);
1830 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001831}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001832#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001833
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001834#ifdef HAVE_LCHOWN
1835PyDoc_STRVAR(posix_lchown__doc__,
1836"lchown(path, uid, gid)\n\n\
1837Change the owner and group id of path to the numeric uid and gid.\n\
1838This function will not follow symbolic links.");
1839
1840static PyObject *
1841posix_lchown(PyObject *self, PyObject *args)
1842{
1843 char *path = NULL;
1844 int uid, gid;
1845 int res;
1846 if (!PyArg_ParseTuple(args, "etii:lchown",
1847 Py_FileSystemDefaultEncoding, &path,
1848 &uid, &gid))
1849 return NULL;
1850 Py_BEGIN_ALLOW_THREADS
1851 res = lchown(path, (uid_t) uid, (gid_t) gid);
1852 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001853 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001854 return posix_error_with_allocated_filename(path);
1855 PyMem_Free(path);
1856 Py_INCREF(Py_None);
1857 return Py_None;
1858}
1859#endif /* HAVE_LCHOWN */
1860
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001861
Guido van Rossum36bc6801995-06-14 22:54:23 +00001862#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001863PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001864"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001865Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001866
Barry Warsaw53699e91996-12-10 23:23:01 +00001867static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001868posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001869{
1870 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001871 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001872
Barry Warsaw53699e91996-12-10 23:23:01 +00001873 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001874#if defined(PYOS_OS2) && defined(PYCC_GCC)
1875 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001876#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001877 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001878#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001879 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001880 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001881 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001882 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001883}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001884
1885PyDoc_STRVAR(posix_getcwdu__doc__,
1886"getcwdu() -> path\n\n\
1887Return a unicode string representing the current working directory.");
1888
1889static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001890posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001891{
1892 char buf[1026];
1893 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001894
1895#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001896 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001897 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001898 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001899 wchar_t *wbuf2 = wbuf;
1900 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001901 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001902 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
1903 /* If the buffer is large enough, len does not include the
1904 terminating \0. If the buffer is too small, len includes
1905 the space needed for the terminator. */
1906 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
1907 wbuf2 = malloc(len * sizeof(wchar_t));
1908 if (wbuf2)
1909 len = GetCurrentDirectoryW(len, wbuf2);
1910 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001911 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001912 if (!wbuf2) {
1913 PyErr_NoMemory();
1914 return NULL;
1915 }
1916 if (!len) {
1917 if (wbuf2 != wbuf) free(wbuf2);
1918 return win32_error("getcwdu", NULL);
1919 }
1920 resobj = PyUnicode_FromWideChar(wbuf2, len);
1921 if (wbuf2 != wbuf) free(wbuf2);
1922 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001923 }
1924#endif
1925
1926 Py_BEGIN_ALLOW_THREADS
1927#if defined(PYOS_OS2) && defined(PYCC_GCC)
1928 res = _getcwd2(buf, sizeof buf);
1929#else
1930 res = getcwd(buf, sizeof buf);
1931#endif
1932 Py_END_ALLOW_THREADS
1933 if (res == NULL)
1934 return posix_error();
1935 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1936}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001937#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001938
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001939
Guido van Rossumb6775db1994-08-01 11:34:53 +00001940#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001941PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001942"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001943Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001944
Barry Warsaw53699e91996-12-10 23:23:01 +00001945static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001946posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001947{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001948 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001949}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001950#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001951
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001952
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001953PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001954"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001955Return a list containing the names of the entries in the directory.\n\
1956\n\
1957 path: path of directory to list\n\
1958\n\
1959The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001960entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001961
Barry Warsaw53699e91996-12-10 23:23:01 +00001962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001963posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001964{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001965 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001966 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001967#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001968
Barry Warsaw53699e91996-12-10 23:23:01 +00001969 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001970 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001971 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001972 WIN32_FIND_DATA FileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001973 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00001974 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001975 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001976
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001977#ifdef Py_WIN_WIDE_FILENAMES
1978 /* If on wide-character-capable OS see if argument
1979 is Unicode and if so use wide API. */
1980 if (unicode_file_names()) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001981 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001982 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1983 WIN32_FIND_DATAW wFileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001984 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001985 Py_UNICODE wch;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001986 /* Overallocate for \\*.*\0 */
1987 len = PyUnicode_GET_SIZE(po);
1988 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
1989 if (!wnamebuf) {
1990 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001991 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001992 }
1993 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
1994 wch = len > 0 ? wnamebuf[len-1] : '\0';
1995 if (wch != L'/' && wch != L'\\' && wch != L':')
1996 wnamebuf[len++] = L'\\';
1997 wcscpy(wnamebuf + len, L"*.*");
1998 if ((d = PyList_New(0)) == NULL) {
1999 free(wnamebuf);
2000 return NULL;
2001 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002002 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2003 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002004 int error = GetLastError();
2005 if (error == ERROR_FILE_NOT_FOUND) {
2006 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002007 return d;
2008 }
2009 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002010 win32_error_unicode("FindFirstFileW", wnamebuf);
2011 free(wnamebuf);
2012 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002013 }
2014 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002015 /* Skip over . and .. */
2016 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2017 wcscmp(wFileData.cFileName, L"..") != 0) {
2018 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2019 if (v == NULL) {
2020 Py_DECREF(d);
2021 d = NULL;
2022 break;
2023 }
2024 if (PyList_Append(d, v) != 0) {
2025 Py_DECREF(v);
2026 Py_DECREF(d);
2027 d = NULL;
2028 break;
2029 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002030 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002031 }
Georg Brandl622927b2006-03-07 12:48:03 +00002032 Py_BEGIN_ALLOW_THREADS
2033 result = FindNextFileW(hFindFile, &wFileData);
2034 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002035 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2036 it got to the end of the directory. */
2037 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2038 Py_DECREF(d);
2039 win32_error_unicode("FindNextFileW", wnamebuf);
2040 FindClose(hFindFile);
2041 free(wnamebuf);
2042 return NULL;
2043 }
Georg Brandl622927b2006-03-07 12:48:03 +00002044 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002045
2046 if (FindClose(hFindFile) == FALSE) {
2047 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002048 win32_error_unicode("FindClose", wnamebuf);
2049 free(wnamebuf);
2050 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002051 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002052 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002053 return d;
2054 }
2055 /* Drop the argument parsing error as narrow strings
2056 are also valid. */
2057 PyErr_Clear();
2058 }
2059#endif
2060
Tim Peters5aa91602002-01-30 05:46:57 +00002061 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002062 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002063 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002064 if (len > 0) {
2065 char ch = namebuf[len-1];
2066 if (ch != SEP && ch != ALTSEP && ch != ':')
2067 namebuf[len++] = '/';
2068 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002069 strcpy(namebuf + len, "*.*");
2070
Barry Warsaw53699e91996-12-10 23:23:01 +00002071 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002072 return NULL;
2073
2074 hFindFile = FindFirstFile(namebuf, &FileData);
2075 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002076 int error = GetLastError();
2077 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002078 return d;
2079 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002080 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002081 }
2082 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002083 /* Skip over . and .. */
2084 if (strcmp(FileData.cFileName, ".") != 0 &&
2085 strcmp(FileData.cFileName, "..") != 0) {
2086 v = PyString_FromString(FileData.cFileName);
2087 if (v == NULL) {
2088 Py_DECREF(d);
2089 d = NULL;
2090 break;
2091 }
2092 if (PyList_Append(d, v) != 0) {
2093 Py_DECREF(v);
2094 Py_DECREF(d);
2095 d = NULL;
2096 break;
2097 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002098 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002099 }
Georg Brandl622927b2006-03-07 12:48:03 +00002100 Py_BEGIN_ALLOW_THREADS
2101 result = FindNextFile(hFindFile, &FileData);
2102 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002103 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2104 it got to the end of the directory. */
2105 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2106 Py_DECREF(d);
2107 win32_error("FindNextFile", namebuf);
2108 FindClose(hFindFile);
2109 return NULL;
2110 }
Georg Brandl622927b2006-03-07 12:48:03 +00002111 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002112
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002113 if (FindClose(hFindFile) == FALSE) {
2114 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002115 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002116 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002117
2118 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002119
Tim Peters0bb44a42000-09-15 07:44:49 +00002120#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002121
2122#ifndef MAX_PATH
2123#define MAX_PATH CCHMAXPATH
2124#endif
2125 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002126 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002127 PyObject *d, *v;
2128 char namebuf[MAX_PATH+5];
2129 HDIR hdir = 1;
2130 ULONG srchcnt = 1;
2131 FILEFINDBUF3 ep;
2132 APIRET rc;
2133
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002134 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002135 return NULL;
2136 if (len >= MAX_PATH) {
2137 PyErr_SetString(PyExc_ValueError, "path too long");
2138 return NULL;
2139 }
2140 strcpy(namebuf, name);
2141 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002142 if (*pt == ALTSEP)
2143 *pt = SEP;
2144 if (namebuf[len-1] != SEP)
2145 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002146 strcpy(namebuf + len, "*.*");
2147
2148 if ((d = PyList_New(0)) == NULL)
2149 return NULL;
2150
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002151 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2152 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002153 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002154 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2155 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2156 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002157
2158 if (rc != NO_ERROR) {
2159 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002160 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002161 }
2162
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002163 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002164 do {
2165 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002166 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002167 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002168
2169 strcpy(namebuf, ep.achName);
2170
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002171 /* Leave Case of Name Alone -- In Native Form */
2172 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002173
2174 v = PyString_FromString(namebuf);
2175 if (v == NULL) {
2176 Py_DECREF(d);
2177 d = NULL;
2178 break;
2179 }
2180 if (PyList_Append(d, v) != 0) {
2181 Py_DECREF(v);
2182 Py_DECREF(d);
2183 d = NULL;
2184 break;
2185 }
2186 Py_DECREF(v);
2187 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2188 }
2189
2190 return d;
2191#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002192
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002193 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002194 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002195 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002196 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002197 int arg_is_unicode = 1;
2198
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002199 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002200 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2201 arg_is_unicode = 0;
2202 PyErr_Clear();
2203 }
2204 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002205 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002206 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002207 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002208 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002209 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002210 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002211 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002212 return NULL;
2213 }
Georg Brandl622927b2006-03-07 12:48:03 +00002214 for (;;) {
2215 Py_BEGIN_ALLOW_THREADS
2216 ep = readdir(dirp);
2217 Py_END_ALLOW_THREADS
2218 if (ep == NULL)
2219 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002220 if (ep->d_name[0] == '.' &&
2221 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002222 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002223 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00002224 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002225 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002226 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002227 d = NULL;
2228 break;
2229 }
Just van Rossum96b1c902003-03-03 17:32:15 +00002230 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002231 PyObject *w;
2232
2233 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002234 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002235 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002236 if (w != NULL) {
2237 Py_DECREF(v);
2238 v = w;
2239 }
2240 else {
2241 /* fall back to the original byte string, as
2242 discussed in patch #683592 */
2243 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002244 }
Just van Rossum46c97842003-02-25 21:42:15 +00002245 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002246 if (PyList_Append(d, v) != 0) {
2247 Py_DECREF(v);
2248 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002249 d = NULL;
2250 break;
2251 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002252 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002253 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002254 if (errno != 0 && d != NULL) {
2255 /* readdir() returned NULL and set errno */
2256 closedir(dirp);
2257 Py_DECREF(d);
2258 return posix_error_with_allocated_filename(name);
2259 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002260 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002261 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002262
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002263 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002264
Tim Peters0bb44a42000-09-15 07:44:49 +00002265#endif /* which OS */
2266} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002267
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002268#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002269/* A helper function for abspath on win32 */
2270static PyObject *
2271posix__getfullpathname(PyObject *self, PyObject *args)
2272{
2273 /* assume encoded strings wont more than double no of chars */
2274 char inbuf[MAX_PATH*2];
2275 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002276 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002277 char outbuf[MAX_PATH*2];
2278 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002279#ifdef Py_WIN_WIDE_FILENAMES
2280 if (unicode_file_names()) {
2281 PyUnicodeObject *po;
2282 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2283 Py_UNICODE woutbuf[MAX_PATH*2];
2284 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002285 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002286 sizeof(woutbuf)/sizeof(woutbuf[0]),
2287 woutbuf, &wtemp))
2288 return win32_error("GetFullPathName", "");
2289 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2290 }
2291 /* Drop the argument parsing error as narrow strings
2292 are also valid. */
2293 PyErr_Clear();
2294 }
2295#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002296 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2297 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002298 &insize))
2299 return NULL;
2300 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2301 outbuf, &temp))
2302 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002303 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2304 return PyUnicode_Decode(outbuf, strlen(outbuf),
2305 Py_FileSystemDefaultEncoding, NULL);
2306 }
Mark Hammondef8b6542001-05-13 08:04:26 +00002307 return PyString_FromString(outbuf);
2308} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002309#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002310
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002311PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002312"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002313Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002314
Barry Warsaw53699e91996-12-10 23:23:01 +00002315static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002316posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002317{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002318 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002319 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002320 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002321
2322#ifdef Py_WIN_WIDE_FILENAMES
2323 if (unicode_file_names()) {
2324 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002325 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002326 Py_BEGIN_ALLOW_THREADS
2327 /* PyUnicode_AS_UNICODE OK without thread lock as
2328 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002329 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002330 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002331 if (!res)
2332 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002333 Py_INCREF(Py_None);
2334 return Py_None;
2335 }
2336 /* Drop the argument parsing error as narrow strings
2337 are also valid. */
2338 PyErr_Clear();
2339 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002340 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2341 Py_FileSystemDefaultEncoding, &path, &mode))
2342 return NULL;
2343 Py_BEGIN_ALLOW_THREADS
2344 /* PyUnicode_AS_UNICODE OK without thread lock as
2345 it is a simple dereference. */
2346 res = CreateDirectoryA(path, NULL);
2347 Py_END_ALLOW_THREADS
2348 if (!res) {
2349 win32_error("mkdir", path);
2350 PyMem_Free(path);
2351 return NULL;
2352 }
2353 PyMem_Free(path);
2354 Py_INCREF(Py_None);
2355 return Py_None;
2356#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002357
Tim Peters5aa91602002-01-30 05:46:57 +00002358 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002359 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002360 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002361 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002362#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002363 res = mkdir(path);
2364#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002365 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002366#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002367 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002368 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002369 return posix_error_with_allocated_filename(path);
2370 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002371 Py_INCREF(Py_None);
2372 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002373#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002374}
2375
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002376
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002377/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2378#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002379#include <sys/resource.h>
2380#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002381
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002382
2383#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002384PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002385"nice(inc) -> new_priority\n\n\
2386Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002387
Barry Warsaw53699e91996-12-10 23:23:01 +00002388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002389posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002390{
2391 int increment, value;
2392
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002393 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002394 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002395
2396 /* There are two flavours of 'nice': one that returns the new
2397 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002398 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2399 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002400
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002401 If we are of the nice family that returns the new priority, we
2402 need to clear errno before the call, and check if errno is filled
2403 before calling posix_error() on a returnvalue of -1, because the
2404 -1 may be the actual new priority! */
2405
2406 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002407 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002408#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002409 if (value == 0)
2410 value = getpriority(PRIO_PROCESS, 0);
2411#endif
2412 if (value == -1 && errno != 0)
2413 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002414 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002415 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002416}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002417#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002418
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002419PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002420"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002421Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002422
Barry Warsaw53699e91996-12-10 23:23:01 +00002423static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002424posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002425{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002426#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002427 PyObject *o1, *o2;
2428 char *p1, *p2;
2429 BOOL result;
2430 if (unicode_file_names()) {
2431 if (!PyArg_ParseTuple(args, "O&O&:rename",
2432 convert_to_unicode, &o1,
2433 convert_to_unicode, &o2))
2434 PyErr_Clear();
2435 else {
2436 Py_BEGIN_ALLOW_THREADS
2437 result = MoveFileW(PyUnicode_AsUnicode(o1),
2438 PyUnicode_AsUnicode(o2));
2439 Py_END_ALLOW_THREADS
2440 Py_DECREF(o1);
2441 Py_DECREF(o2);
2442 if (!result)
2443 return win32_error("rename", NULL);
2444 Py_INCREF(Py_None);
2445 return Py_None;
2446 }
2447 }
2448 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2449 return NULL;
2450 Py_BEGIN_ALLOW_THREADS
2451 result = MoveFileA(p1, p2);
2452 Py_END_ALLOW_THREADS
2453 if (!result)
2454 return win32_error("rename", NULL);
2455 Py_INCREF(Py_None);
2456 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002457#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002458 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002459#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002460}
2461
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002462
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002463PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002464"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002465Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002466
Barry Warsaw53699e91996-12-10 23:23:01 +00002467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002468posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002469{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002470#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002471 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002472#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002473 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002474#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002475}
2476
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002477
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002478PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002479"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002480Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002481
Barry Warsaw53699e91996-12-10 23:23:01 +00002482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002483posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002484{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002485#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002486 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002487#else
2488 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2489#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002490}
2491
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002492
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002493#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002494PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002495"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002496Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002497
Barry Warsaw53699e91996-12-10 23:23:01 +00002498static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002499posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002500{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002501 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002502 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002503 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002504 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002505 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002506 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002507 Py_END_ALLOW_THREADS
2508 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002509}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002510#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002511
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002512
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002513PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002514"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002515Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002516
Barry Warsaw53699e91996-12-10 23:23:01 +00002517static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002518posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002519{
2520 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002521 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002522 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002523 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002524 if (i < 0)
2525 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002526 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002527}
2528
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002529
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002530PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002531"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002532Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002533
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002534PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002535"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002536Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002537
Barry Warsaw53699e91996-12-10 23:23:01 +00002538static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002539posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002540{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002541#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002542 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002543#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002544 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002545#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002546}
2547
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002548
Guido van Rossumb6775db1994-08-01 11:34:53 +00002549#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002550PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002551"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002552Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002553
Barry Warsaw53699e91996-12-10 23:23:01 +00002554static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002555posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002556{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002557 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002558 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002559
Barry Warsaw53699e91996-12-10 23:23:01 +00002560 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002561 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002562 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002563 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002564 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002565 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002566 u.sysname,
2567 u.nodename,
2568 u.release,
2569 u.version,
2570 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002571}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002572#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002573
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002574static int
2575extract_time(PyObject *t, long* sec, long* usec)
2576{
2577 long intval;
2578 if (PyFloat_Check(t)) {
2579 double tval = PyFloat_AsDouble(t);
2580 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2581 if (!intobj)
2582 return -1;
2583 intval = PyInt_AsLong(intobj);
2584 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002585 if (intval == -1 && PyErr_Occurred())
2586 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002587 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002588 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002589 if (*usec < 0)
2590 /* If rounding gave us a negative number,
2591 truncate. */
2592 *usec = 0;
2593 return 0;
2594 }
2595 intval = PyInt_AsLong(t);
2596 if (intval == -1 && PyErr_Occurred())
2597 return -1;
2598 *sec = intval;
2599 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002600 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002601}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002602
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002603PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002604"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002605utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002606Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002607second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002608
Barry Warsaw53699e91996-12-10 23:23:01 +00002609static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002610posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002611{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002612#ifdef Py_WIN_WIDE_FILENAMES
2613 PyObject *arg;
2614 PyUnicodeObject *obwpath;
2615 wchar_t *wpath = NULL;
2616 char *apath = NULL;
2617 HANDLE hFile;
2618 long atimesec, mtimesec, ausec, musec;
2619 FILETIME atime, mtime;
2620 PyObject *result = NULL;
2621
2622 if (unicode_file_names()) {
2623 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2624 wpath = PyUnicode_AS_UNICODE(obwpath);
2625 Py_BEGIN_ALLOW_THREADS
2626 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002627 NULL, OPEN_EXISTING,
2628 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002629 Py_END_ALLOW_THREADS
2630 if (hFile == INVALID_HANDLE_VALUE)
2631 return win32_error_unicode("utime", wpath);
2632 } else
2633 /* Drop the argument parsing error as narrow strings
2634 are also valid. */
2635 PyErr_Clear();
2636 }
2637 if (!wpath) {
2638 if (!PyArg_ParseTuple(args, "etO:utime",
2639 Py_FileSystemDefaultEncoding, &apath, &arg))
2640 return NULL;
2641 Py_BEGIN_ALLOW_THREADS
2642 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002643 NULL, OPEN_EXISTING,
2644 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002645 Py_END_ALLOW_THREADS
2646 if (hFile == INVALID_HANDLE_VALUE) {
2647 win32_error("utime", apath);
2648 PyMem_Free(apath);
2649 return NULL;
2650 }
2651 PyMem_Free(apath);
2652 }
2653
2654 if (arg == Py_None) {
2655 SYSTEMTIME now;
2656 GetSystemTime(&now);
2657 if (!SystemTimeToFileTime(&now, &mtime) ||
2658 !SystemTimeToFileTime(&now, &atime)) {
2659 win32_error("utime", NULL);
2660 goto done;
2661 }
2662 }
2663 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2664 PyErr_SetString(PyExc_TypeError,
2665 "utime() arg 2 must be a tuple (atime, mtime)");
2666 goto done;
2667 }
2668 else {
2669 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2670 &atimesec, &ausec) == -1)
2671 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002672 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002673 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2674 &mtimesec, &musec) == -1)
2675 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002676 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002677 }
2678 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2679 /* Avoid putting the file name into the error here,
2680 as that may confuse the user into believing that
2681 something is wrong with the file, when it also
2682 could be the time stamp that gives a problem. */
2683 win32_error("utime", NULL);
2684 }
2685 Py_INCREF(Py_None);
2686 result = Py_None;
2687done:
2688 CloseHandle(hFile);
2689 return result;
2690#else /* Py_WIN_WIDE_FILENAMES */
2691
Neal Norwitz2adf2102004-06-09 01:46:02 +00002692 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002693 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002694 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002695 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002696
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002697#if defined(HAVE_UTIMES)
2698 struct timeval buf[2];
2699#define ATIME buf[0].tv_sec
2700#define MTIME buf[1].tv_sec
2701#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002702/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002703 struct utimbuf buf;
2704#define ATIME buf.actime
2705#define MTIME buf.modtime
2706#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002707#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002708 time_t buf[2];
2709#define ATIME buf[0]
2710#define MTIME buf[1]
2711#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002712#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002713
Mark Hammond817c9292003-12-03 01:22:38 +00002714
Thomas Wouters477c8d52006-05-27 19:21:47 +00002715 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002716 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002717 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002718 if (arg == Py_None) {
2719 /* optional time values not given */
2720 Py_BEGIN_ALLOW_THREADS
2721 res = utime(path, NULL);
2722 Py_END_ALLOW_THREADS
2723 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002724 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002725 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002726 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002727 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002728 return NULL;
2729 }
2730 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002731 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002732 &atime, &ausec) == -1) {
2733 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002734 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002735 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002736 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002737 &mtime, &musec) == -1) {
2738 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002739 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002740 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002741 ATIME = atime;
2742 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002743#ifdef HAVE_UTIMES
2744 buf[0].tv_usec = ausec;
2745 buf[1].tv_usec = musec;
2746 Py_BEGIN_ALLOW_THREADS
2747 res = utimes(path, buf);
2748 Py_END_ALLOW_THREADS
2749#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002750 Py_BEGIN_ALLOW_THREADS
2751 res = utime(path, UTIME_ARG);
2752 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002753#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002754 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002755 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002756 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002757 }
Neal Norwitz96652712004-06-06 20:40:27 +00002758 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002759 Py_INCREF(Py_None);
2760 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002761#undef UTIME_ARG
2762#undef ATIME
2763#undef MTIME
Thomas Wouters477c8d52006-05-27 19:21:47 +00002764#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002765}
2766
Guido van Rossum85e3b011991-06-03 12:42:10 +00002767
Guido van Rossum3b066191991-06-04 19:40:25 +00002768/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002769
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002770PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002771"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002772Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002773
Barry Warsaw53699e91996-12-10 23:23:01 +00002774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002775posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002776{
2777 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002778 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002779 return NULL;
2780 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002781 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002782}
2783
Martin v. Löwis114619e2002-10-07 06:44:21 +00002784#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2785static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002786free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002787{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002788 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002789 for (i = 0; i < count; i++)
2790 PyMem_Free(array[i]);
2791 PyMem_DEL(array);
2792}
2793#endif
2794
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002795
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002796#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002797PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002798"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002799Execute an executable path with arguments, replacing current process.\n\
2800\n\
2801 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002802 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002803
Barry Warsaw53699e91996-12-10 23:23:01 +00002804static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002805posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002806{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002807 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002808 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002809 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002810 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002811 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002812
Guido van Rossum89b33251993-10-22 14:26:06 +00002813 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002814 argv is a list or tuple of strings. */
2815
Martin v. Löwis114619e2002-10-07 06:44:21 +00002816 if (!PyArg_ParseTuple(args, "etO:execv",
2817 Py_FileSystemDefaultEncoding,
2818 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002819 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002820 if (PyList_Check(argv)) {
2821 argc = PyList_Size(argv);
2822 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002823 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002824 else if (PyTuple_Check(argv)) {
2825 argc = PyTuple_Size(argv);
2826 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002827 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002828 else {
Fred Drake661ea262000-10-24 19:57:45 +00002829 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002830 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002831 return NULL;
2832 }
2833
Barry Warsaw53699e91996-12-10 23:23:01 +00002834 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002835 if (argvlist == NULL) {
2836 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002837 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002838 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002839 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002840 if (!PyArg_Parse((*getitem)(argv, i), "et",
2841 Py_FileSystemDefaultEncoding,
2842 &argvlist[i])) {
2843 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002844 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002845 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002846 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002847 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002848
Guido van Rossum85e3b011991-06-03 12:42:10 +00002849 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002850 }
2851 argvlist[argc] = NULL;
2852
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002853 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002854
Guido van Rossum85e3b011991-06-03 12:42:10 +00002855 /* If we get here it's definitely an error */
2856
Martin v. Löwis114619e2002-10-07 06:44:21 +00002857 free_string_array(argvlist, argc);
2858 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002859 return posix_error();
2860}
2861
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002862
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002863PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002864"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002865Execute a path with arguments and environment, replacing current process.\n\
2866\n\
2867 path: path of executable file\n\
2868 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002869 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002870
Barry Warsaw53699e91996-12-10 23:23:01 +00002871static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002872posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002873{
2874 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002875 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002876 char **argvlist;
2877 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002878 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002879 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002880 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002881 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002882
2883 /* execve has three arguments: (path, argv, env), where
2884 argv is a list or tuple of strings and env is a dictionary
2885 like posix.environ. */
2886
Martin v. Löwis114619e2002-10-07 06:44:21 +00002887 if (!PyArg_ParseTuple(args, "etOO:execve",
2888 Py_FileSystemDefaultEncoding,
2889 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002890 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002891 if (PyList_Check(argv)) {
2892 argc = PyList_Size(argv);
2893 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002894 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002895 else if (PyTuple_Check(argv)) {
2896 argc = PyTuple_Size(argv);
2897 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002898 }
2899 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002900 PyErr_SetString(PyExc_TypeError,
2901 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002902 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002903 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002904 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002905 PyErr_SetString(PyExc_TypeError,
2906 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002907 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002908 }
2909
Barry Warsaw53699e91996-12-10 23:23:01 +00002910 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002911 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002912 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002913 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002914 }
2915 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002916 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002917 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002918 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002919 &argvlist[i]))
2920 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002921 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002922 goto fail_1;
2923 }
2924 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002925 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002926 argvlist[argc] = NULL;
2927
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002928 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002929 if (i < 0)
2930 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002931 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002932 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002933 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002934 goto fail_1;
2935 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002936 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002937 keys = PyMapping_Keys(env);
2938 vals = PyMapping_Values(env);
2939 if (!keys || !vals)
2940 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002941 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2942 PyErr_SetString(PyExc_TypeError,
2943 "execve(): env.keys() or env.values() is not a list");
2944 goto fail_2;
2945 }
Tim Peters5aa91602002-01-30 05:46:57 +00002946
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002947 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002948 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002949 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002950
2951 key = PyList_GetItem(keys, pos);
2952 val = PyList_GetItem(vals, pos);
2953 if (!key || !val)
2954 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002955
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002956 if (!PyArg_Parse(
2957 key,
2958 "s;execve() arg 3 contains a non-string key",
2959 &k) ||
2960 !PyArg_Parse(
2961 val,
2962 "s;execve() arg 3 contains a non-string value",
2963 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002964 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002965 goto fail_2;
2966 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002967
2968#if defined(PYOS_OS2)
2969 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2970 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2971#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002972 len = PyString_Size(key) + PyString_Size(val) + 2;
2973 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002974 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002975 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002976 goto fail_2;
2977 }
Tim Petersc8996f52001-12-03 20:41:00 +00002978 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002979 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002980#if defined(PYOS_OS2)
2981 }
2982#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002983 }
2984 envlist[envc] = 0;
2985
2986 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002987
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002988 /* If we get here it's definitely an error */
2989
2990 (void) posix_error();
2991
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002992 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002993 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002994 PyMem_DEL(envlist[envc]);
2995 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002996 fail_1:
2997 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002998 Py_XDECREF(vals);
2999 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003000 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003001 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003002 return NULL;
3003}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003004#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003006
Guido van Rossuma1065681999-01-25 23:20:23 +00003007#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003008PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003009"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003010Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003011\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003012 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003013 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003014 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003015
3016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003017posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003018{
3019 char *path;
3020 PyObject *argv;
3021 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003022 int mode, i;
3023 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003024 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003025 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003026
3027 /* spawnv has three arguments: (mode, path, argv), where
3028 argv is a list or tuple of strings. */
3029
Martin v. Löwis114619e2002-10-07 06:44:21 +00003030 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3031 Py_FileSystemDefaultEncoding,
3032 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003033 return NULL;
3034 if (PyList_Check(argv)) {
3035 argc = PyList_Size(argv);
3036 getitem = PyList_GetItem;
3037 }
3038 else if (PyTuple_Check(argv)) {
3039 argc = PyTuple_Size(argv);
3040 getitem = PyTuple_GetItem;
3041 }
3042 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003043 PyErr_SetString(PyExc_TypeError,
3044 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003045 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003046 return NULL;
3047 }
3048
3049 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003050 if (argvlist == NULL) {
3051 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003052 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003053 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003054 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003055 if (!PyArg_Parse((*getitem)(argv, i), "et",
3056 Py_FileSystemDefaultEncoding,
3057 &argvlist[i])) {
3058 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003059 PyErr_SetString(
3060 PyExc_TypeError,
3061 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003062 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003063 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003064 }
3065 }
3066 argvlist[argc] = NULL;
3067
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003068#if defined(PYOS_OS2) && defined(PYCC_GCC)
3069 Py_BEGIN_ALLOW_THREADS
3070 spawnval = spawnv(mode, path, argvlist);
3071 Py_END_ALLOW_THREADS
3072#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003073 if (mode == _OLD_P_OVERLAY)
3074 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003075
Tim Peters25059d32001-12-07 20:35:43 +00003076 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003077 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003078 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003079#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003080
Martin v. Löwis114619e2002-10-07 06:44:21 +00003081 free_string_array(argvlist, argc);
3082 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003083
Fred Drake699f3522000-06-29 21:12:41 +00003084 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003085 return posix_error();
3086 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003087#if SIZEOF_LONG == SIZEOF_VOID_P
3088 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003089#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003090 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003091#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003092}
3093
3094
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003095PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003096"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003097Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003098\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003099 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003100 path: path of executable file\n\
3101 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003102 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003103
3104static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003105posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003106{
3107 char *path;
3108 PyObject *argv, *env;
3109 char **argvlist;
3110 char **envlist;
3111 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003112 int mode, pos, envc;
3113 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003114 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003115 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003116 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003117
3118 /* spawnve has four arguments: (mode, path, argv, env), where
3119 argv is a list or tuple of strings and env is a dictionary
3120 like posix.environ. */
3121
Martin v. Löwis114619e2002-10-07 06:44:21 +00003122 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3123 Py_FileSystemDefaultEncoding,
3124 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003125 return NULL;
3126 if (PyList_Check(argv)) {
3127 argc = PyList_Size(argv);
3128 getitem = PyList_GetItem;
3129 }
3130 else if (PyTuple_Check(argv)) {
3131 argc = PyTuple_Size(argv);
3132 getitem = PyTuple_GetItem;
3133 }
3134 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003135 PyErr_SetString(PyExc_TypeError,
3136 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003137 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003138 }
3139 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003140 PyErr_SetString(PyExc_TypeError,
3141 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003142 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003143 }
3144
3145 argvlist = PyMem_NEW(char *, argc+1);
3146 if (argvlist == NULL) {
3147 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003148 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003149 }
3150 for (i = 0; i < argc; i++) {
3151 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003152 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003153 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003154 &argvlist[i]))
3155 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003156 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003157 goto fail_1;
3158 }
3159 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003160 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003161 argvlist[argc] = NULL;
3162
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003163 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003164 if (i < 0)
3165 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003166 envlist = PyMem_NEW(char *, i + 1);
3167 if (envlist == NULL) {
3168 PyErr_NoMemory();
3169 goto fail_1;
3170 }
3171 envc = 0;
3172 keys = PyMapping_Keys(env);
3173 vals = PyMapping_Values(env);
3174 if (!keys || !vals)
3175 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003176 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3177 PyErr_SetString(PyExc_TypeError,
3178 "spawnve(): env.keys() or env.values() is not a list");
3179 goto fail_2;
3180 }
Tim Peters5aa91602002-01-30 05:46:57 +00003181
Guido van Rossuma1065681999-01-25 23:20:23 +00003182 for (pos = 0; pos < i; pos++) {
3183 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003184 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003185
3186 key = PyList_GetItem(keys, pos);
3187 val = PyList_GetItem(vals, pos);
3188 if (!key || !val)
3189 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003190
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003191 if (!PyArg_Parse(
3192 key,
3193 "s;spawnve() arg 3 contains a non-string key",
3194 &k) ||
3195 !PyArg_Parse(
3196 val,
3197 "s;spawnve() arg 3 contains a non-string value",
3198 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003199 {
3200 goto fail_2;
3201 }
Tim Petersc8996f52001-12-03 20:41:00 +00003202 len = PyString_Size(key) + PyString_Size(val) + 2;
3203 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003204 if (p == NULL) {
3205 PyErr_NoMemory();
3206 goto fail_2;
3207 }
Tim Petersc8996f52001-12-03 20:41:00 +00003208 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003209 envlist[envc++] = p;
3210 }
3211 envlist[envc] = 0;
3212
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003213#if defined(PYOS_OS2) && defined(PYCC_GCC)
3214 Py_BEGIN_ALLOW_THREADS
3215 spawnval = spawnve(mode, path, argvlist, envlist);
3216 Py_END_ALLOW_THREADS
3217#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003218 if (mode == _OLD_P_OVERLAY)
3219 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003220
3221 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003222 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003223 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003224#endif
Tim Peters25059d32001-12-07 20:35:43 +00003225
Fred Drake699f3522000-06-29 21:12:41 +00003226 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003227 (void) posix_error();
3228 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003229#if SIZEOF_LONG == SIZEOF_VOID_P
3230 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003231#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003232 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003233#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003234
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003235 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003236 while (--envc >= 0)
3237 PyMem_DEL(envlist[envc]);
3238 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003239 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003240 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003241 Py_XDECREF(vals);
3242 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003243 fail_0:
3244 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003245 return res;
3246}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003247
3248/* OS/2 supports spawnvp & spawnvpe natively */
3249#if defined(PYOS_OS2)
3250PyDoc_STRVAR(posix_spawnvp__doc__,
3251"spawnvp(mode, file, args)\n\n\
3252Execute the program 'file' in a new process, using the environment\n\
3253search path to find the file.\n\
3254\n\
3255 mode: mode of process creation\n\
3256 file: executable file name\n\
3257 args: tuple or list of strings");
3258
3259static PyObject *
3260posix_spawnvp(PyObject *self, PyObject *args)
3261{
3262 char *path;
3263 PyObject *argv;
3264 char **argvlist;
3265 int mode, i, argc;
3266 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003267 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003268
3269 /* spawnvp has three arguments: (mode, path, argv), where
3270 argv is a list or tuple of strings. */
3271
3272 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3273 Py_FileSystemDefaultEncoding,
3274 &path, &argv))
3275 return NULL;
3276 if (PyList_Check(argv)) {
3277 argc = PyList_Size(argv);
3278 getitem = PyList_GetItem;
3279 }
3280 else if (PyTuple_Check(argv)) {
3281 argc = PyTuple_Size(argv);
3282 getitem = PyTuple_GetItem;
3283 }
3284 else {
3285 PyErr_SetString(PyExc_TypeError,
3286 "spawnvp() arg 2 must be a tuple or list");
3287 PyMem_Free(path);
3288 return NULL;
3289 }
3290
3291 argvlist = PyMem_NEW(char *, argc+1);
3292 if (argvlist == NULL) {
3293 PyMem_Free(path);
3294 return PyErr_NoMemory();
3295 }
3296 for (i = 0; i < argc; i++) {
3297 if (!PyArg_Parse((*getitem)(argv, i), "et",
3298 Py_FileSystemDefaultEncoding,
3299 &argvlist[i])) {
3300 free_string_array(argvlist, i);
3301 PyErr_SetString(
3302 PyExc_TypeError,
3303 "spawnvp() arg 2 must contain only strings");
3304 PyMem_Free(path);
3305 return NULL;
3306 }
3307 }
3308 argvlist[argc] = NULL;
3309
3310 Py_BEGIN_ALLOW_THREADS
3311#if defined(PYCC_GCC)
3312 spawnval = spawnvp(mode, path, argvlist);
3313#else
3314 spawnval = _spawnvp(mode, path, argvlist);
3315#endif
3316 Py_END_ALLOW_THREADS
3317
3318 free_string_array(argvlist, argc);
3319 PyMem_Free(path);
3320
3321 if (spawnval == -1)
3322 return posix_error();
3323 else
3324 return Py_BuildValue("l", (long) spawnval);
3325}
3326
3327
3328PyDoc_STRVAR(posix_spawnvpe__doc__,
3329"spawnvpe(mode, file, args, env)\n\n\
3330Execute the program 'file' in a new process, using the environment\n\
3331search path to find the file.\n\
3332\n\
3333 mode: mode of process creation\n\
3334 file: executable file name\n\
3335 args: tuple or list of arguments\n\
3336 env: dictionary of strings mapping to strings");
3337
3338static PyObject *
3339posix_spawnvpe(PyObject *self, PyObject *args)
3340{
3341 char *path;
3342 PyObject *argv, *env;
3343 char **argvlist;
3344 char **envlist;
3345 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3346 int mode, i, pos, argc, envc;
3347 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003348 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003349 int lastarg = 0;
3350
3351 /* spawnvpe has four arguments: (mode, path, argv, env), where
3352 argv is a list or tuple of strings and env is a dictionary
3353 like posix.environ. */
3354
3355 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3356 Py_FileSystemDefaultEncoding,
3357 &path, &argv, &env))
3358 return NULL;
3359 if (PyList_Check(argv)) {
3360 argc = PyList_Size(argv);
3361 getitem = PyList_GetItem;
3362 }
3363 else if (PyTuple_Check(argv)) {
3364 argc = PyTuple_Size(argv);
3365 getitem = PyTuple_GetItem;
3366 }
3367 else {
3368 PyErr_SetString(PyExc_TypeError,
3369 "spawnvpe() arg 2 must be a tuple or list");
3370 goto fail_0;
3371 }
3372 if (!PyMapping_Check(env)) {
3373 PyErr_SetString(PyExc_TypeError,
3374 "spawnvpe() arg 3 must be a mapping object");
3375 goto fail_0;
3376 }
3377
3378 argvlist = PyMem_NEW(char *, argc+1);
3379 if (argvlist == NULL) {
3380 PyErr_NoMemory();
3381 goto fail_0;
3382 }
3383 for (i = 0; i < argc; i++) {
3384 if (!PyArg_Parse((*getitem)(argv, i),
3385 "et;spawnvpe() arg 2 must contain only strings",
3386 Py_FileSystemDefaultEncoding,
3387 &argvlist[i]))
3388 {
3389 lastarg = i;
3390 goto fail_1;
3391 }
3392 }
3393 lastarg = argc;
3394 argvlist[argc] = NULL;
3395
3396 i = PyMapping_Size(env);
3397 if (i < 0)
3398 goto fail_1;
3399 envlist = PyMem_NEW(char *, i + 1);
3400 if (envlist == NULL) {
3401 PyErr_NoMemory();
3402 goto fail_1;
3403 }
3404 envc = 0;
3405 keys = PyMapping_Keys(env);
3406 vals = PyMapping_Values(env);
3407 if (!keys || !vals)
3408 goto fail_2;
3409 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3410 PyErr_SetString(PyExc_TypeError,
3411 "spawnvpe(): env.keys() or env.values() is not a list");
3412 goto fail_2;
3413 }
3414
3415 for (pos = 0; pos < i; pos++) {
3416 char *p, *k, *v;
3417 size_t len;
3418
3419 key = PyList_GetItem(keys, pos);
3420 val = PyList_GetItem(vals, pos);
3421 if (!key || !val)
3422 goto fail_2;
3423
3424 if (!PyArg_Parse(
3425 key,
3426 "s;spawnvpe() arg 3 contains a non-string key",
3427 &k) ||
3428 !PyArg_Parse(
3429 val,
3430 "s;spawnvpe() arg 3 contains a non-string value",
3431 &v))
3432 {
3433 goto fail_2;
3434 }
3435 len = PyString_Size(key) + PyString_Size(val) + 2;
3436 p = PyMem_NEW(char, len);
3437 if (p == NULL) {
3438 PyErr_NoMemory();
3439 goto fail_2;
3440 }
3441 PyOS_snprintf(p, len, "%s=%s", k, v);
3442 envlist[envc++] = p;
3443 }
3444 envlist[envc] = 0;
3445
3446 Py_BEGIN_ALLOW_THREADS
3447#if defined(PYCC_GCC)
3448 spawnval = spawnve(mode, path, argvlist, envlist);
3449#else
3450 spawnval = _spawnve(mode, path, argvlist, envlist);
3451#endif
3452 Py_END_ALLOW_THREADS
3453
3454 if (spawnval == -1)
3455 (void) posix_error();
3456 else
3457 res = Py_BuildValue("l", (long) spawnval);
3458
3459 fail_2:
3460 while (--envc >= 0)
3461 PyMem_DEL(envlist[envc]);
3462 PyMem_DEL(envlist);
3463 fail_1:
3464 free_string_array(argvlist, lastarg);
3465 Py_XDECREF(vals);
3466 Py_XDECREF(keys);
3467 fail_0:
3468 PyMem_Free(path);
3469 return res;
3470}
3471#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003472#endif /* HAVE_SPAWNV */
3473
3474
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003475#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003476PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003477"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003478Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3479\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003480Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003481
3482static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003483posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003484{
Neal Norwitze241ce82003-02-17 18:17:05 +00003485 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003486 if (pid == -1)
3487 return posix_error();
3488 PyOS_AfterFork();
3489 return PyInt_FromLong((long)pid);
3490}
3491#endif
3492
3493
Guido van Rossumad0ee831995-03-01 10:34:45 +00003494#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003495PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003496"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003497Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003498Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003499
Barry Warsaw53699e91996-12-10 23:23:01 +00003500static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003501posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003502{
Neal Norwitze241ce82003-02-17 18:17:05 +00003503 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003504 if (pid == -1)
3505 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003506 if (pid == 0)
3507 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003508 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003509}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003510#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003511
Neal Norwitzb59798b2003-03-21 01:43:31 +00003512/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003513/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3514#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003515#define DEV_PTY_FILE "/dev/ptc"
3516#define HAVE_DEV_PTMX
3517#else
3518#define DEV_PTY_FILE "/dev/ptmx"
3519#endif
3520
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003521#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003522#ifdef HAVE_PTY_H
3523#include <pty.h>
3524#else
3525#ifdef HAVE_LIBUTIL_H
3526#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003527#endif /* HAVE_LIBUTIL_H */
3528#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003529#ifdef HAVE_STROPTS_H
3530#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003531#endif
3532#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003533
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003534#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003535PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003536"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003537Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003538
3539static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003540posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003541{
3542 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003543#ifndef HAVE_OPENPTY
3544 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003545#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003546#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003547 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003548#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003549 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003550#endif
3551#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003552
Thomas Wouters70c21a12000-07-14 14:28:33 +00003553#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003554 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3555 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003556#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003557 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3558 if (slave_name == NULL)
3559 return posix_error();
3560
3561 slave_fd = open(slave_name, O_RDWR);
3562 if (slave_fd < 0)
3563 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003564#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003565 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003566 if (master_fd < 0)
3567 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003568 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003569 /* change permission of slave */
3570 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003571 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003572 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003573 }
3574 /* unlock slave */
3575 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003576 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003577 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003578 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003579 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003580 slave_name = ptsname(master_fd); /* get name of slave */
3581 if (slave_name == NULL)
3582 return posix_error();
3583 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3584 if (slave_fd < 0)
3585 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003586#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003587 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3588 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003589#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003590 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003591#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003592#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003593#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003594
Fred Drake8cef4cf2000-06-28 16:40:38 +00003595 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003596
Fred Drake8cef4cf2000-06-28 16:40:38 +00003597}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003598#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003599
3600#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003601PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003602"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003603Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3604Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003605To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003606
3607static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003608posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003609{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003610 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003611
Fred Drake8cef4cf2000-06-28 16:40:38 +00003612 pid = forkpty(&master_fd, NULL, NULL, NULL);
3613 if (pid == -1)
3614 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003615 if (pid == 0)
3616 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003617 return Py_BuildValue("(ii)", pid, master_fd);
3618}
3619#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003620
Guido van Rossumad0ee831995-03-01 10:34:45 +00003621#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003622PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003623"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003624Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003625
Barry Warsaw53699e91996-12-10 23:23:01 +00003626static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003627posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003628{
Barry Warsaw53699e91996-12-10 23:23:01 +00003629 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003630}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003631#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003632
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003633
Guido van Rossumad0ee831995-03-01 10:34:45 +00003634#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003635PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003636"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003637Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003638
Barry Warsaw53699e91996-12-10 23:23:01 +00003639static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003640posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003641{
Barry Warsaw53699e91996-12-10 23:23:01 +00003642 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003643}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003644#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003645
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003646
Guido van Rossumad0ee831995-03-01 10:34:45 +00003647#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003648PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003649"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003650Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003651
Barry Warsaw53699e91996-12-10 23:23:01 +00003652static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003653posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003654{
Barry Warsaw53699e91996-12-10 23:23:01 +00003655 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003656}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003657#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003658
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003659
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003660PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003661"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003662Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003663
Barry Warsaw53699e91996-12-10 23:23:01 +00003664static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003665posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003666{
Barry Warsaw53699e91996-12-10 23:23:01 +00003667 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003668}
3669
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003670
Fred Drakec9680921999-12-13 16:37:25 +00003671#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003672PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003673"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003674Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003675
3676static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003677posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003678{
3679 PyObject *result = NULL;
3680
Fred Drakec9680921999-12-13 16:37:25 +00003681#ifdef NGROUPS_MAX
3682#define MAX_GROUPS NGROUPS_MAX
3683#else
3684 /* defined to be 16 on Solaris7, so this should be a small number */
3685#define MAX_GROUPS 64
3686#endif
3687 gid_t grouplist[MAX_GROUPS];
3688 int n;
3689
3690 n = getgroups(MAX_GROUPS, grouplist);
3691 if (n < 0)
3692 posix_error();
3693 else {
3694 result = PyList_New(n);
3695 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003696 int i;
3697 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003698 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003699 if (o == NULL) {
3700 Py_DECREF(result);
3701 result = NULL;
3702 break;
3703 }
3704 PyList_SET_ITEM(result, i, o);
3705 }
3706 }
3707 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003708
Fred Drakec9680921999-12-13 16:37:25 +00003709 return result;
3710}
3711#endif
3712
Martin v. Löwis606edc12002-06-13 21:09:11 +00003713#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003714PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003715"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003716Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003717
3718static PyObject *
3719posix_getpgid(PyObject *self, PyObject *args)
3720{
3721 int pid, pgid;
3722 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3723 return NULL;
3724 pgid = getpgid(pid);
3725 if (pgid < 0)
3726 return posix_error();
3727 return PyInt_FromLong((long)pgid);
3728}
3729#endif /* HAVE_GETPGID */
3730
3731
Guido van Rossumb6775db1994-08-01 11:34:53 +00003732#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003733PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003734"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003735Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003736
Barry Warsaw53699e91996-12-10 23:23:01 +00003737static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003738posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003739{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003740#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003741 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003742#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003743 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003744#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003745}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003746#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003747
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003748
Guido van Rossumb6775db1994-08-01 11:34:53 +00003749#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003750PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003751"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003752Make this process a session leader.");
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_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003756{
Guido van Rossum64933891994-10-20 21:56:42 +00003757#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003758 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003759#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003760 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003761#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003762 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003763 Py_INCREF(Py_None);
3764 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003765}
3766
Guido van Rossumb6775db1994-08-01 11:34:53 +00003767#endif /* HAVE_SETPGRP */
3768
Guido van Rossumad0ee831995-03-01 10:34:45 +00003769#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003770PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003771"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003772Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003773
Barry Warsaw53699e91996-12-10 23:23:01 +00003774static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003775posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003776{
Barry Warsaw53699e91996-12-10 23:23:01 +00003777 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003778}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003779#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003781
Fred Drake12c6e2d1999-12-14 21:25:03 +00003782#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003783PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003784"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003785Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003786
3787static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003788posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003789{
Neal Norwitze241ce82003-02-17 18:17:05 +00003790 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003791 char *name;
3792 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003793
Fred Drakea30680b2000-12-06 21:24:28 +00003794 errno = 0;
3795 name = getlogin();
3796 if (name == NULL) {
3797 if (errno)
3798 posix_error();
3799 else
3800 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003801 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003802 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003803 else
3804 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003805 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003806
Fred Drake12c6e2d1999-12-14 21:25:03 +00003807 return result;
3808}
3809#endif
3810
Guido van Rossumad0ee831995-03-01 10:34:45 +00003811#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003812PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003813"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003814Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003815
Barry Warsaw53699e91996-12-10 23:23:01 +00003816static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003817posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003818{
Barry Warsaw53699e91996-12-10 23:23:01 +00003819 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003820}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003821#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003822
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003823
Guido van Rossumad0ee831995-03-01 10:34:45 +00003824#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003825PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003826"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003827Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003828
Barry Warsaw53699e91996-12-10 23:23:01 +00003829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003830posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003831{
3832 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003833 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003834 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003835#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003836 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3837 APIRET rc;
3838 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003839 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003840
3841 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3842 APIRET rc;
3843 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003844 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003845
3846 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003847 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003848#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003849 if (kill(pid, sig) == -1)
3850 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003851#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003852 Py_INCREF(Py_None);
3853 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003854}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003855#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003856
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003857#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003858PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003859"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003860Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003861
3862static PyObject *
3863posix_killpg(PyObject *self, PyObject *args)
3864{
3865 int pgid, sig;
3866 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3867 return NULL;
3868 if (killpg(pgid, sig) == -1)
3869 return posix_error();
3870 Py_INCREF(Py_None);
3871 return Py_None;
3872}
3873#endif
3874
Guido van Rossumc0125471996-06-28 18:55:32 +00003875#ifdef HAVE_PLOCK
3876
3877#ifdef HAVE_SYS_LOCK_H
3878#include <sys/lock.h>
3879#endif
3880
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003881PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003882"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003883Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003884
Barry Warsaw53699e91996-12-10 23:23:01 +00003885static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003886posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003887{
3888 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003889 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003890 return NULL;
3891 if (plock(op) == -1)
3892 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003893 Py_INCREF(Py_None);
3894 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003895}
3896#endif
3897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003898
Guido van Rossum3b066191991-06-04 19:40:25 +00003899
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003900
Guido van Rossumb6775db1994-08-01 11:34:53 +00003901#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003902PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003903"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003904Set the current process's user id.");
3905
Barry Warsaw53699e91996-12-10 23:23:01 +00003906static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003907posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003908{
3909 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003910 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003911 return NULL;
3912 if (setuid(uid) < 0)
3913 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003914 Py_INCREF(Py_None);
3915 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003916}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003917#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003918
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003919
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003920#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003921PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003922"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003923Set the current process's effective user id.");
3924
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003925static PyObject *
3926posix_seteuid (PyObject *self, PyObject *args)
3927{
3928 int euid;
3929 if (!PyArg_ParseTuple(args, "i", &euid)) {
3930 return NULL;
3931 } else if (seteuid(euid) < 0) {
3932 return posix_error();
3933 } else {
3934 Py_INCREF(Py_None);
3935 return Py_None;
3936 }
3937}
3938#endif /* HAVE_SETEUID */
3939
3940#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003941PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003942"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003943Set the current process's effective group id.");
3944
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003945static PyObject *
3946posix_setegid (PyObject *self, PyObject *args)
3947{
3948 int egid;
3949 if (!PyArg_ParseTuple(args, "i", &egid)) {
3950 return NULL;
3951 } else if (setegid(egid) < 0) {
3952 return posix_error();
3953 } else {
3954 Py_INCREF(Py_None);
3955 return Py_None;
3956 }
3957}
3958#endif /* HAVE_SETEGID */
3959
3960#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003961PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00003962"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003963Set the current process's real and effective user ids.");
3964
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003965static PyObject *
3966posix_setreuid (PyObject *self, PyObject *args)
3967{
3968 int ruid, euid;
3969 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3970 return NULL;
3971 } else if (setreuid(ruid, euid) < 0) {
3972 return posix_error();
3973 } else {
3974 Py_INCREF(Py_None);
3975 return Py_None;
3976 }
3977}
3978#endif /* HAVE_SETREUID */
3979
3980#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003981PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00003982"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003983Set the current process's real and effective group ids.");
3984
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003985static PyObject *
3986posix_setregid (PyObject *self, PyObject *args)
3987{
3988 int rgid, egid;
3989 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3990 return NULL;
3991 } else if (setregid(rgid, egid) < 0) {
3992 return posix_error();
3993 } else {
3994 Py_INCREF(Py_None);
3995 return Py_None;
3996 }
3997}
3998#endif /* HAVE_SETREGID */
3999
Guido van Rossumb6775db1994-08-01 11:34:53 +00004000#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004001PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004002"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004003Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004004
Barry Warsaw53699e91996-12-10 23:23:01 +00004005static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004006posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004007{
4008 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004009 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004010 return NULL;
4011 if (setgid(gid) < 0)
4012 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004013 Py_INCREF(Py_None);
4014 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004015}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004016#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004017
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004018#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004019PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004020"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004021Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004022
4023static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004024posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004025{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004026 int i, len;
4027 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004028
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004029 if (!PySequence_Check(groups)) {
4030 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4031 return NULL;
4032 }
4033 len = PySequence_Size(groups);
4034 if (len > MAX_GROUPS) {
4035 PyErr_SetString(PyExc_ValueError, "too many groups");
4036 return NULL;
4037 }
4038 for(i = 0; i < len; i++) {
4039 PyObject *elem;
4040 elem = PySequence_GetItem(groups, i);
4041 if (!elem)
4042 return NULL;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004043 if (!PyLong_Check(elem)) {
4044 PyErr_SetString(PyExc_TypeError,
4045 "groups must be integers");
4046 Py_DECREF(elem);
4047 return NULL;
4048 } else {
4049 unsigned long x = PyLong_AsUnsignedLong(elem);
4050 if (PyErr_Occurred()) {
4051 PyErr_SetString(PyExc_TypeError,
4052 "group id too big");
Georg Brandla13c2442005-11-22 19:30:31 +00004053 Py_DECREF(elem);
4054 return NULL;
Georg Brandla13c2442005-11-22 19:30:31 +00004055 }
Georg Brandla13c2442005-11-22 19:30:31 +00004056 grouplist[i] = x;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004057 /* read back the value to see if it fitted in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00004058 if (grouplist[i] != x) {
4059 PyErr_SetString(PyExc_TypeError,
4060 "group id too big");
4061 Py_DECREF(elem);
4062 return NULL;
4063 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004064 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004065 Py_DECREF(elem);
4066 }
4067
4068 if (setgroups(len, grouplist) < 0)
4069 return posix_error();
4070 Py_INCREF(Py_None);
4071 return Py_None;
4072}
4073#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004074
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004075#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4076static PyObject *
4077wait_helper(int pid, int status, struct rusage *ru)
4078{
4079 PyObject *result;
4080 static PyObject *struct_rusage;
4081
4082 if (pid == -1)
4083 return posix_error();
4084
4085 if (struct_rusage == NULL) {
4086 PyObject *m = PyImport_ImportModule("resource");
4087 if (m == NULL)
4088 return NULL;
4089 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4090 Py_DECREF(m);
4091 if (struct_rusage == NULL)
4092 return NULL;
4093 }
4094
4095 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4096 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4097 if (!result)
4098 return NULL;
4099
4100#ifndef doubletime
4101#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4102#endif
4103
4104 PyStructSequence_SET_ITEM(result, 0,
4105 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4106 PyStructSequence_SET_ITEM(result, 1,
4107 PyFloat_FromDouble(doubletime(ru->ru_stime)));
4108#define SET_INT(result, index, value)\
4109 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
4110 SET_INT(result, 2, ru->ru_maxrss);
4111 SET_INT(result, 3, ru->ru_ixrss);
4112 SET_INT(result, 4, ru->ru_idrss);
4113 SET_INT(result, 5, ru->ru_isrss);
4114 SET_INT(result, 6, ru->ru_minflt);
4115 SET_INT(result, 7, ru->ru_majflt);
4116 SET_INT(result, 8, ru->ru_nswap);
4117 SET_INT(result, 9, ru->ru_inblock);
4118 SET_INT(result, 10, ru->ru_oublock);
4119 SET_INT(result, 11, ru->ru_msgsnd);
4120 SET_INT(result, 12, ru->ru_msgrcv);
4121 SET_INT(result, 13, ru->ru_nsignals);
4122 SET_INT(result, 14, ru->ru_nvcsw);
4123 SET_INT(result, 15, ru->ru_nivcsw);
4124#undef SET_INT
4125
4126 if (PyErr_Occurred()) {
4127 Py_DECREF(result);
4128 return NULL;
4129 }
4130
4131 return Py_BuildValue("iiN", pid, status, result);
4132}
4133#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4134
4135#ifdef HAVE_WAIT3
4136PyDoc_STRVAR(posix_wait3__doc__,
4137"wait3(options) -> (pid, status, rusage)\n\n\
4138Wait for completion of a child process.");
4139
4140static PyObject *
4141posix_wait3(PyObject *self, PyObject *args)
4142{
4143 int pid, options;
4144 struct rusage ru;
4145 WAIT_TYPE status;
4146 WAIT_STATUS_INT(status) = 0;
4147
4148 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4149 return NULL;
4150
4151 Py_BEGIN_ALLOW_THREADS
4152 pid = wait3(&status, options, &ru);
4153 Py_END_ALLOW_THREADS
4154
4155 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4156}
4157#endif /* HAVE_WAIT3 */
4158
4159#ifdef HAVE_WAIT4
4160PyDoc_STRVAR(posix_wait4__doc__,
4161"wait4(pid, options) -> (pid, status, rusage)\n\n\
4162Wait for completion of a given child process.");
4163
4164static PyObject *
4165posix_wait4(PyObject *self, PyObject *args)
4166{
4167 int pid, options;
4168 struct rusage ru;
4169 WAIT_TYPE status;
4170 WAIT_STATUS_INT(status) = 0;
4171
4172 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
4173 return NULL;
4174
4175 Py_BEGIN_ALLOW_THREADS
4176 pid = wait4(pid, &status, options, &ru);
4177 Py_END_ALLOW_THREADS
4178
4179 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4180}
4181#endif /* HAVE_WAIT4 */
4182
Guido van Rossumb6775db1994-08-01 11:34:53 +00004183#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004184PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004185"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004186Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004187
Barry Warsaw53699e91996-12-10 23:23:01 +00004188static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004189posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004190{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004191 int pid, options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004192 WAIT_TYPE status;
4193 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004194
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004195 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004196 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004197 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004198 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004199 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004200 if (pid == -1)
4201 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004202
4203 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004204}
4205
Tim Petersab034fa2002-02-01 11:27:43 +00004206#elif defined(HAVE_CWAIT)
4207
4208/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004209PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004210"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004211"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004212
4213static PyObject *
4214posix_waitpid(PyObject *self, PyObject *args)
4215{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004216 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004217 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004218
4219 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4220 return NULL;
4221 Py_BEGIN_ALLOW_THREADS
4222 pid = _cwait(&status, pid, options);
4223 Py_END_ALLOW_THREADS
4224 if (pid == -1)
4225 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004226
4227 /* shift the status left a byte so this is more like the POSIX waitpid */
4228 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004229}
4230#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004231
Guido van Rossumad0ee831995-03-01 10:34:45 +00004232#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004233PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004234"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004235Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004236
Barry Warsaw53699e91996-12-10 23:23:01 +00004237static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004238posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004239{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004240 int pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004241 WAIT_TYPE status;
4242 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004243
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004244 Py_BEGIN_ALLOW_THREADS
4245 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004246 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004247 if (pid == -1)
4248 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004249
4250 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004251}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004252#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004253
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004254
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004255PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004256"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004257Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004258
Barry Warsaw53699e91996-12-10 23:23:01 +00004259static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004260posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004261{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004262#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004263 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004264#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004265#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00004266 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004267#else
4268 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4269#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004270#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004271}
4272
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004273
Guido van Rossumb6775db1994-08-01 11:34:53 +00004274#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004275PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004276"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004277Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004278
Barry Warsaw53699e91996-12-10 23:23:01 +00004279static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004280posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004281{
Thomas Wouters89f507f2006-12-13 04:49:30 +00004282 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004283 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004284 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004285 int n;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004286 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004287
4288 if (!PyArg_ParseTuple(args, "et:readlink",
4289 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004290 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004291 v = PySequence_GetItem(args, 0);
4292 if (v == NULL) return NULL;
4293
4294 if (PyUnicode_Check(v)) {
4295 arg_is_unicode = 1;
4296 }
4297 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004298
Barry Warsaw53699e91996-12-10 23:23:01 +00004299 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004300 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004301 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004302 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004303 return posix_error_with_filename(path);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004304
4305 v = PyString_FromStringAndSize(buf, n);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004306 if (arg_is_unicode) {
4307 PyObject *w;
4308
4309 w = PyUnicode_FromEncodedObject(v,
4310 Py_FileSystemDefaultEncoding,
4311 "strict");
4312 if (w != NULL) {
4313 Py_DECREF(v);
4314 v = w;
4315 }
4316 else {
4317 /* fall back to the original byte string, as
4318 discussed in patch #683592 */
4319 PyErr_Clear();
4320 }
4321 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004322 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004323}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004324#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004325
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004326
Guido van Rossumb6775db1994-08-01 11:34:53 +00004327#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004328PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004329"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004330Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004331
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004332static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004333posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004334{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004335 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004336}
4337#endif /* HAVE_SYMLINK */
4338
4339
4340#ifdef HAVE_TIMES
4341#ifndef HZ
4342#define HZ 60 /* Universal constant :-) */
4343#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004344
Guido van Rossumd48f2521997-12-05 22:19:34 +00004345#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4346static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004347system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004348{
4349 ULONG value = 0;
4350
4351 Py_BEGIN_ALLOW_THREADS
4352 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4353 Py_END_ALLOW_THREADS
4354
4355 return value;
4356}
4357
4358static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004359posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004360{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004361 /* Currently Only Uptime is Provided -- Others Later */
4362 return Py_BuildValue("ddddd",
4363 (double)0 /* t.tms_utime / HZ */,
4364 (double)0 /* t.tms_stime / HZ */,
4365 (double)0 /* t.tms_cutime / HZ */,
4366 (double)0 /* t.tms_cstime / HZ */,
4367 (double)system_uptime() / 1000);
4368}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004369#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004370static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004371posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004372{
4373 struct tms t;
4374 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004375 errno = 0;
4376 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004377 if (c == (clock_t) -1)
4378 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004379 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004380 (double)t.tms_utime / HZ,
4381 (double)t.tms_stime / HZ,
4382 (double)t.tms_cutime / HZ,
4383 (double)t.tms_cstime / HZ,
4384 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004385}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004386#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004387#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004388
4389
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004390#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004391#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004392static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004393posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004394{
4395 FILETIME create, exit, kernel, user;
4396 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004397 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004398 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4399 /* The fields of a FILETIME structure are the hi and lo part
4400 of a 64-bit value expressed in 100 nanosecond units.
4401 1e7 is one second in such units; 1e-7 the inverse.
4402 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4403 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004404 return Py_BuildValue(
4405 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004406 (double)(kernel.dwHighDateTime*429.4967296 +
4407 kernel.dwLowDateTime*1e-7),
4408 (double)(user.dwHighDateTime*429.4967296 +
4409 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004410 (double)0,
4411 (double)0,
4412 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004413}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004414#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004415
4416#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004417PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004418"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004419Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004420#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004421
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004422
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004423#ifdef HAVE_GETSID
4424PyDoc_STRVAR(posix_getsid__doc__,
4425"getsid(pid) -> sid\n\n\
4426Call the system call getsid().");
4427
4428static PyObject *
4429posix_getsid(PyObject *self, PyObject *args)
4430{
4431 int pid, sid;
4432 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
4433 return NULL;
4434 sid = getsid(pid);
4435 if (sid < 0)
4436 return posix_error();
4437 return PyInt_FromLong((long)sid);
4438}
4439#endif /* HAVE_GETSID */
4440
4441
Guido van Rossumb6775db1994-08-01 11:34:53 +00004442#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004443PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004444"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004445Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004446
Barry Warsaw53699e91996-12-10 23:23:01 +00004447static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004448posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004449{
Guido van Rossum687dd131993-05-17 08:34:16 +00004450 if (setsid() < 0)
4451 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004452 Py_INCREF(Py_None);
4453 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004454}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004455#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004456
Guido van Rossumb6775db1994-08-01 11:34:53 +00004457#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004458PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004459"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004460Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004461
Barry Warsaw53699e91996-12-10 23:23:01 +00004462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004463posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004464{
4465 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004466 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004467 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004468 if (setpgid(pid, pgrp) < 0)
4469 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004470 Py_INCREF(Py_None);
4471 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004472}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004473#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004474
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004475
Guido van Rossumb6775db1994-08-01 11:34:53 +00004476#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004477PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004478"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004479Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004480
Barry Warsaw53699e91996-12-10 23:23:01 +00004481static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004482posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004483{
4484 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004485 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004486 return NULL;
4487 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004488 if (pgid < 0)
4489 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004490 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004491}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004492#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004493
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004494
Guido van Rossumb6775db1994-08-01 11:34:53 +00004495#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004496PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004497"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004498Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004499
Barry Warsaw53699e91996-12-10 23:23:01 +00004500static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004501posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004502{
4503 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004504 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004505 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004506 if (tcsetpgrp(fd, pgid) < 0)
4507 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004508 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004509 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004510}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004511#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004512
Guido van Rossum687dd131993-05-17 08:34:16 +00004513/* Functions acting on file descriptors */
4514
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004515PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004516"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004517Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004518
Barry Warsaw53699e91996-12-10 23:23:01 +00004519static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004520posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004521{
Mark Hammondef8b6542001-05-13 08:04:26 +00004522 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004523 int flag;
4524 int mode = 0777;
4525 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004526
4527#ifdef MS_WINDOWS
4528 if (unicode_file_names()) {
4529 PyUnicodeObject *po;
4530 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4531 Py_BEGIN_ALLOW_THREADS
4532 /* PyUnicode_AS_UNICODE OK without thread
4533 lock as it is a simple dereference. */
4534 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4535 Py_END_ALLOW_THREADS
4536 if (fd < 0)
4537 return posix_error();
4538 return PyInt_FromLong((long)fd);
4539 }
4540 /* Drop the argument parsing error as narrow strings
4541 are also valid. */
4542 PyErr_Clear();
4543 }
4544#endif
4545
Tim Peters5aa91602002-01-30 05:46:57 +00004546 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004547 Py_FileSystemDefaultEncoding, &file,
4548 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004549 return NULL;
4550
Barry Warsaw53699e91996-12-10 23:23:01 +00004551 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004552 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004553 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004554 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004555 return posix_error_with_allocated_filename(file);
4556 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004557 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004558}
4559
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004560
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004561PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004562"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004563Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004564
Barry Warsaw53699e91996-12-10 23:23:01 +00004565static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004566posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004567{
4568 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004569 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004570 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004571 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004572 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004573 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004574 if (res < 0)
4575 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004576 Py_INCREF(Py_None);
4577 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004578}
4579
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004580
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004581PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004582"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004583Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004584
Barry Warsaw53699e91996-12-10 23:23:01 +00004585static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004586posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004587{
4588 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004589 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004590 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004591 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004592 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004593 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004594 if (fd < 0)
4595 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004596 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004597}
4598
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004599
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004600PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00004601"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004602Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004603
Barry Warsaw53699e91996-12-10 23:23:01 +00004604static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004605posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004606{
4607 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004608 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004609 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004610 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004611 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004612 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004613 if (res < 0)
4614 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004615 Py_INCREF(Py_None);
4616 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004617}
4618
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004619
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004620PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004621"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004622Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004623
Barry Warsaw53699e91996-12-10 23:23:01 +00004624static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004625posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004626{
4627 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004628#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00004629 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004630#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004631 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004632#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004633 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004634 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004635 return NULL;
4636#ifdef SEEK_SET
4637 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4638 switch (how) {
4639 case 0: how = SEEK_SET; break;
4640 case 1: how = SEEK_CUR; break;
4641 case 2: how = SEEK_END; break;
4642 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004643#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004644
4645#if !defined(HAVE_LARGEFILE_SUPPORT)
4646 pos = PyInt_AsLong(posobj);
4647#else
4648 pos = PyLong_Check(posobj) ?
4649 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4650#endif
4651 if (PyErr_Occurred())
4652 return NULL;
4653
Barry Warsaw53699e91996-12-10 23:23:01 +00004654 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004655#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004656 res = _lseeki64(fd, pos, how);
4657#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004658 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004659#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004660 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004661 if (res < 0)
4662 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004663
4664#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004665 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004666#else
4667 return PyLong_FromLongLong(res);
4668#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004669}
4670
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004671
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004672PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004673"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004674Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004675
Barry Warsaw53699e91996-12-10 23:23:01 +00004676static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004677posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004678{
Guido van Rossum572dbf82007-04-27 23:53:51 +00004679 int fd, size;
4680 Py_ssize_t n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004681 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004682 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004683 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00004684 if (size < 0) {
4685 errno = EINVAL;
4686 return posix_error();
4687 }
Guido van Rossum572dbf82007-04-27 23:53:51 +00004688 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004689 if (buffer == NULL)
4690 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004691 Py_BEGIN_ALLOW_THREADS
Guido van Rossum572dbf82007-04-27 23:53:51 +00004692 n = read(fd, PyBytes_AsString(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004693 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004694 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004695 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004696 return posix_error();
4697 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004698 if (n != size)
Guido van Rossum572dbf82007-04-27 23:53:51 +00004699 PyBytes_Resize(buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004700 return buffer;
4701}
4702
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004703
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004704PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004705"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004706Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004707
Barry Warsaw53699e91996-12-10 23:23:01 +00004708static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004709posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004710{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004711 int fd;
4712 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00004713 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004714
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004715 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004716 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004717 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004718 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004719 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004720 if (size < 0)
4721 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004722 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004723}
4724
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004725
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004726PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004727"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004728Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004729
Barry Warsaw53699e91996-12-10 23:23:01 +00004730static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004731posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004732{
4733 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004734 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004735 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004736 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004737 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00004738#ifdef __VMS
4739 /* on OpenVMS we must ensure that all bytes are written to the file */
4740 fsync(fd);
4741#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004742 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004743 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004744 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00004745 if (res != 0) {
4746#ifdef MS_WINDOWS
4747 return win32_error("fstat", NULL);
4748#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004749 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00004750#endif
4751 }
Tim Peters5aa91602002-01-30 05:46:57 +00004752
Martin v. Löwis14694662006-02-03 12:54:16 +00004753 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004754}
4755
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004756PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004757"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004758Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004759connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004760
4761static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004762posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004763{
4764 int fd;
4765 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4766 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004767 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004768}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004769
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004770#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004771PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004772"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004773Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004774
Barry Warsaw53699e91996-12-10 23:23:01 +00004775static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004776posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00004777{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004778#if defined(PYOS_OS2)
4779 HFILE read, write;
4780 APIRET rc;
4781
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004782 Py_BEGIN_ALLOW_THREADS
4783 rc = DosCreatePipe( &read, &write, 4096);
4784 Py_END_ALLOW_THREADS
4785 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004786 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004787
4788 return Py_BuildValue("(ii)", read, write);
4789#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004790#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00004791 int fds[2];
4792 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00004793 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004794 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004795 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004796 if (res != 0)
4797 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004798 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004799#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00004800 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004801 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004802 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00004803 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004804 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004805 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004806 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004807 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004808 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4809 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004810 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004811#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004812#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004813}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004814#endif /* HAVE_PIPE */
4815
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004816
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004817#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004818PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00004819"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004820Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004821
Barry Warsaw53699e91996-12-10 23:23:01 +00004822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004823posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004824{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004825 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004826 int mode = 0666;
4827 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004828 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004829 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004830 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004831 res = mkfifo(filename, mode);
4832 Py_END_ALLOW_THREADS
4833 if (res < 0)
4834 return posix_error();
4835 Py_INCREF(Py_None);
4836 return Py_None;
4837}
4838#endif
4839
4840
Neal Norwitz11690112002-07-30 01:08:28 +00004841#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004842PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00004843"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004844Create a filesystem node (file, device special file or named pipe)\n\
4845named filename. mode specifies both the permissions to use and the\n\
4846type of node to be created, being combined (bitwise OR) with one of\n\
4847S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004848device defines the newly created device special file (probably using\n\
4849os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004850
4851
4852static PyObject *
4853posix_mknod(PyObject *self, PyObject *args)
4854{
4855 char *filename;
4856 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004857 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004858 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00004859 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004860 return NULL;
4861 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004862 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00004863 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004864 if (res < 0)
4865 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004866 Py_INCREF(Py_None);
4867 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004868}
4869#endif
4870
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004871#ifdef HAVE_DEVICE_MACROS
4872PyDoc_STRVAR(posix_major__doc__,
4873"major(device) -> major number\n\
4874Extracts a device major number from a raw device number.");
4875
4876static PyObject *
4877posix_major(PyObject *self, PyObject *args)
4878{
4879 int device;
4880 if (!PyArg_ParseTuple(args, "i:major", &device))
4881 return NULL;
4882 return PyInt_FromLong((long)major(device));
4883}
4884
4885PyDoc_STRVAR(posix_minor__doc__,
4886"minor(device) -> minor number\n\
4887Extracts a device minor number from a raw device number.");
4888
4889static PyObject *
4890posix_minor(PyObject *self, PyObject *args)
4891{
4892 int device;
4893 if (!PyArg_ParseTuple(args, "i:minor", &device))
4894 return NULL;
4895 return PyInt_FromLong((long)minor(device));
4896}
4897
4898PyDoc_STRVAR(posix_makedev__doc__,
4899"makedev(major, minor) -> device number\n\
4900Composes a raw device number from the major and minor device numbers.");
4901
4902static PyObject *
4903posix_makedev(PyObject *self, PyObject *args)
4904{
4905 int major, minor;
4906 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
4907 return NULL;
4908 return PyInt_FromLong((long)makedev(major, minor));
4909}
4910#endif /* device macros */
4911
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004912
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004913#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004914PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004915"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004916Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004917
Barry Warsaw53699e91996-12-10 23:23:01 +00004918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004919posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004920{
4921 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004922 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004923 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004924 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004925
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004926 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004927 return NULL;
4928
4929#if !defined(HAVE_LARGEFILE_SUPPORT)
4930 length = PyInt_AsLong(lenobj);
4931#else
4932 length = PyLong_Check(lenobj) ?
4933 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4934#endif
4935 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004936 return NULL;
4937
Barry Warsaw53699e91996-12-10 23:23:01 +00004938 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004939 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004940 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004941 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004942 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004943 return NULL;
4944 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004945 Py_INCREF(Py_None);
4946 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004947}
4948#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004949
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004950#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004951PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004952"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004953Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004954
Fred Drake762e2061999-08-26 17:23:54 +00004955/* Save putenv() parameters as values here, so we can collect them when they
4956 * get re-set with another call for the same key. */
4957static PyObject *posix_putenv_garbage;
4958
Tim Peters5aa91602002-01-30 05:46:57 +00004959static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004960posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004961{
4962 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004963 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00004964 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004965 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004966
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004967 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004968 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004969
4970#if defined(PYOS_OS2)
4971 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4972 APIRET rc;
4973
Guido van Rossumd48f2521997-12-05 22:19:34 +00004974 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4975 if (rc != NO_ERROR)
4976 return os2_error(rc);
4977
4978 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4979 APIRET rc;
4980
Guido van Rossumd48f2521997-12-05 22:19:34 +00004981 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4982 if (rc != NO_ERROR)
4983 return os2_error(rc);
4984 } else {
4985#endif
4986
Fred Drake762e2061999-08-26 17:23:54 +00004987 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004988 len = strlen(s1) + strlen(s2) + 2;
4989 /* len includes space for a trailing \0; the size arg to
4990 PyString_FromStringAndSize does not count that */
4991 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004992 if (newstr == NULL)
4993 return PyErr_NoMemory();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004994 newenv = PyString_AS_STRING(newstr);
4995 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
4996 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00004997 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004998 posix_error();
4999 return NULL;
5000 }
Fred Drake762e2061999-08-26 17:23:54 +00005001 /* Install the first arg and newstr in posix_putenv_garbage;
5002 * this will cause previous value to be collected. This has to
5003 * happen after the real putenv() call because the old value
5004 * was still accessible until then. */
5005 if (PyDict_SetItem(posix_putenv_garbage,
5006 PyTuple_GET_ITEM(args, 0), newstr)) {
5007 /* really not much we can do; just leak */
5008 PyErr_Clear();
5009 }
5010 else {
5011 Py_DECREF(newstr);
5012 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005013
5014#if defined(PYOS_OS2)
5015 }
5016#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005017 Py_INCREF(Py_None);
5018 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005019}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005020#endif /* putenv */
5021
Guido van Rossumc524d952001-10-19 01:31:59 +00005022#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005023PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005024"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005025Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005026
5027static PyObject *
5028posix_unsetenv(PyObject *self, PyObject *args)
5029{
5030 char *s1;
5031
5032 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5033 return NULL;
5034
5035 unsetenv(s1);
5036
5037 /* Remove the key from posix_putenv_garbage;
5038 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005039 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005040 * old value was still accessible until then.
5041 */
5042 if (PyDict_DelItem(posix_putenv_garbage,
5043 PyTuple_GET_ITEM(args, 0))) {
5044 /* really not much we can do; just leak */
5045 PyErr_Clear();
5046 }
5047
5048 Py_INCREF(Py_None);
5049 return Py_None;
5050}
5051#endif /* unsetenv */
5052
Guido van Rossumb6a47161997-09-15 22:54:34 +00005053#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005054PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005055"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005056Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005057
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005059posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005060{
5061 int code;
5062 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005063 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005064 return NULL;
5065 message = strerror(code);
5066 if (message == NULL) {
5067 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005068 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005069 return NULL;
5070 }
5071 return PyString_FromString(message);
5072}
5073#endif /* strerror */
5074
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005075
Guido van Rossumc9641791998-08-04 15:26:23 +00005076#ifdef HAVE_SYS_WAIT_H
5077
Fred Drake106c1a02002-04-23 15:58:02 +00005078#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005079PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005080"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005081Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005082
5083static PyObject *
5084posix_WCOREDUMP(PyObject *self, PyObject *args)
5085{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005086 WAIT_TYPE status;
5087 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005088
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005089 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005090 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005091
5092 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005093}
5094#endif /* WCOREDUMP */
5095
5096#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005097PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005098"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005099Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005100job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005101
5102static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005103posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005104{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005105 WAIT_TYPE status;
5106 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005107
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005108 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005109 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005110
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005111 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005112}
5113#endif /* WIFCONTINUED */
5114
Guido van Rossumc9641791998-08-04 15:26:23 +00005115#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005116PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005117"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005118Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005119
5120static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005121posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005122{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005123 WAIT_TYPE status;
5124 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005125
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005126 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005127 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005128
Fred Drake106c1a02002-04-23 15:58:02 +00005129 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005130}
5131#endif /* WIFSTOPPED */
5132
5133#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005134PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005135"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005136Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005137
5138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005139posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005140{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005141 WAIT_TYPE status;
5142 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005143
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005144 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005145 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005146
Fred Drake106c1a02002-04-23 15:58:02 +00005147 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005148}
5149#endif /* WIFSIGNALED */
5150
5151#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005152PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005153"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005154Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005155system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005156
5157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005158posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005159{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005160 WAIT_TYPE status;
5161 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005162
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005163 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005164 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005165
Fred Drake106c1a02002-04-23 15:58:02 +00005166 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005167}
5168#endif /* WIFEXITED */
5169
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005170#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005171PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005172"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005173Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005174
5175static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005176posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005177{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005178 WAIT_TYPE status;
5179 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005180
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005181 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005182 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005183
Guido van Rossumc9641791998-08-04 15:26:23 +00005184 return Py_BuildValue("i", WEXITSTATUS(status));
5185}
5186#endif /* WEXITSTATUS */
5187
5188#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005189PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005190"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005191Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005192value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005193
5194static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005195posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005196{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005197 WAIT_TYPE status;
5198 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005199
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005200 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005201 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005202
Guido van Rossumc9641791998-08-04 15:26:23 +00005203 return Py_BuildValue("i", WTERMSIG(status));
5204}
5205#endif /* WTERMSIG */
5206
5207#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005208PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005209"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005210Return the signal that stopped the process that provided\n\
5211the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005212
5213static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005214posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005215{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005216 WAIT_TYPE status;
5217 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005218
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005219 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005220 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005221
Guido van Rossumc9641791998-08-04 15:26:23 +00005222 return Py_BuildValue("i", WSTOPSIG(status));
5223}
5224#endif /* WSTOPSIG */
5225
5226#endif /* HAVE_SYS_WAIT_H */
5227
5228
Thomas Wouters477c8d52006-05-27 19:21:47 +00005229#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005230#ifdef _SCO_DS
5231/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5232 needed definitions in sys/statvfs.h */
5233#define _SVID3
5234#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005235#include <sys/statvfs.h>
5236
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005237static PyObject*
5238_pystatvfs_fromstructstatvfs(struct statvfs st) {
5239 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5240 if (v == NULL)
5241 return NULL;
5242
5243#if !defined(HAVE_LARGEFILE_SUPPORT)
5244 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5245 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5246 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5247 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5248 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5249 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5250 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5251 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5252 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5253 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5254#else
5255 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5256 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005257 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005258 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005259 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005260 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005261 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005262 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005263 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005264 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005265 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005266 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005267 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005268 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005269 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5270 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5271#endif
5272
5273 return v;
5274}
5275
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005276PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005277"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005278Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005279
5280static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005281posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005282{
5283 int fd, res;
5284 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005285
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005286 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005287 return NULL;
5288 Py_BEGIN_ALLOW_THREADS
5289 res = fstatvfs(fd, &st);
5290 Py_END_ALLOW_THREADS
5291 if (res != 0)
5292 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005293
5294 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005295}
Thomas Wouters477c8d52006-05-27 19:21:47 +00005296#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005297
5298
Thomas Wouters477c8d52006-05-27 19:21:47 +00005299#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005300#include <sys/statvfs.h>
5301
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005302PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005303"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005304Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005305
5306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005307posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005308{
5309 char *path;
5310 int res;
5311 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005312 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005313 return NULL;
5314 Py_BEGIN_ALLOW_THREADS
5315 res = statvfs(path, &st);
5316 Py_END_ALLOW_THREADS
5317 if (res != 0)
5318 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005319
5320 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005321}
5322#endif /* HAVE_STATVFS */
5323
5324
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005325#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005326PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005327"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005328Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005329The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005330or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005331
5332static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005333posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005334{
5335 PyObject *result = NULL;
5336 char *dir = NULL;
5337 char *pfx = NULL;
5338 char *name;
5339
5340 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5341 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005342
5343 if (PyErr_Warn(PyExc_RuntimeWarning,
5344 "tempnam is a potential security risk to your program") < 0)
5345 return NULL;
5346
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005347#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005348 name = _tempnam(dir, pfx);
5349#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005350 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005351#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005352 if (name == NULL)
5353 return PyErr_NoMemory();
5354 result = PyString_FromString(name);
5355 free(name);
5356 return result;
5357}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005358#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005359
5360
5361#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005362PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005363"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005364Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005365
5366static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005367posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005368{
5369 FILE *fp;
5370
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005371 fp = tmpfile();
5372 if (fp == NULL)
5373 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005374 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005375}
5376#endif
5377
5378
5379#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005380PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005381"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005382Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005383
5384static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005385posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005386{
5387 char buffer[L_tmpnam];
5388 char *name;
5389
Skip Montanaro95618b52001-08-18 18:52:10 +00005390 if (PyErr_Warn(PyExc_RuntimeWarning,
5391 "tmpnam is a potential security risk to your program") < 0)
5392 return NULL;
5393
Greg Wardb48bc172000-03-01 21:51:56 +00005394#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005395 name = tmpnam_r(buffer);
5396#else
5397 name = tmpnam(buffer);
5398#endif
5399 if (name == NULL) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005400 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005401#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005402 "unexpected NULL from tmpnam_r"
5403#else
5404 "unexpected NULL from tmpnam"
5405#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005406 );
5407 PyErr_SetObject(PyExc_OSError, err);
5408 Py_XDECREF(err);
5409 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005410 }
5411 return PyString_FromString(buffer);
5412}
5413#endif
5414
5415
Fred Drakec9680921999-12-13 16:37:25 +00005416/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5417 * It maps strings representing configuration variable names to
5418 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005419 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005420 * rarely-used constants. There are three separate tables that use
5421 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005422 *
5423 * This code is always included, even if none of the interfaces that
5424 * need it are included. The #if hackery needed to avoid it would be
5425 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005426 */
5427struct constdef {
5428 char *name;
5429 long value;
5430};
5431
Fred Drake12c6e2d1999-12-14 21:25:03 +00005432static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005433conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5434 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005435{
5436 if (PyInt_Check(arg)) {
5437 *valuep = PyInt_AS_LONG(arg);
5438 return 1;
5439 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00005440 else {
Fred Drake12c6e2d1999-12-14 21:25:03 +00005441 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005442 size_t lo = 0;
5443 size_t mid;
5444 size_t hi = tablesize;
5445 int cmp;
Guido van Rossumbce56a62007-05-10 18:04:33 +00005446 const char *confname;
5447 Py_ssize_t namelen;
5448 if (PyObject_AsCharBuffer(arg, &confname, &namelen) < 0) {
5449 PyErr_SetString(PyExc_TypeError,
5450 "configuration names must be strings or integers");
5451 return 0;
5452 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005453 while (lo < hi) {
5454 mid = (lo + hi) / 2;
5455 cmp = strcmp(confname, table[mid].name);
5456 if (cmp < 0)
5457 hi = mid;
5458 else if (cmp > 0)
5459 lo = mid + 1;
5460 else {
5461 *valuep = table[mid].value;
5462 return 1;
5463 }
5464 }
5465 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Guido van Rossumbce56a62007-05-10 18:04:33 +00005466 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005467 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005468}
5469
5470
5471#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5472static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005473#ifdef _PC_ABI_AIO_XFER_MAX
5474 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5475#endif
5476#ifdef _PC_ABI_ASYNC_IO
5477 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5478#endif
Fred Drakec9680921999-12-13 16:37:25 +00005479#ifdef _PC_ASYNC_IO
5480 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5481#endif
5482#ifdef _PC_CHOWN_RESTRICTED
5483 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5484#endif
5485#ifdef _PC_FILESIZEBITS
5486 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5487#endif
5488#ifdef _PC_LAST
5489 {"PC_LAST", _PC_LAST},
5490#endif
5491#ifdef _PC_LINK_MAX
5492 {"PC_LINK_MAX", _PC_LINK_MAX},
5493#endif
5494#ifdef _PC_MAX_CANON
5495 {"PC_MAX_CANON", _PC_MAX_CANON},
5496#endif
5497#ifdef _PC_MAX_INPUT
5498 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5499#endif
5500#ifdef _PC_NAME_MAX
5501 {"PC_NAME_MAX", _PC_NAME_MAX},
5502#endif
5503#ifdef _PC_NO_TRUNC
5504 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5505#endif
5506#ifdef _PC_PATH_MAX
5507 {"PC_PATH_MAX", _PC_PATH_MAX},
5508#endif
5509#ifdef _PC_PIPE_BUF
5510 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5511#endif
5512#ifdef _PC_PRIO_IO
5513 {"PC_PRIO_IO", _PC_PRIO_IO},
5514#endif
5515#ifdef _PC_SOCK_MAXBUF
5516 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5517#endif
5518#ifdef _PC_SYNC_IO
5519 {"PC_SYNC_IO", _PC_SYNC_IO},
5520#endif
5521#ifdef _PC_VDISABLE
5522 {"PC_VDISABLE", _PC_VDISABLE},
5523#endif
5524};
5525
Fred Drakec9680921999-12-13 16:37:25 +00005526static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005527conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005528{
5529 return conv_confname(arg, valuep, posix_constants_pathconf,
5530 sizeof(posix_constants_pathconf)
5531 / sizeof(struct constdef));
5532}
5533#endif
5534
5535#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005536PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005537"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005538Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005539If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005540
5541static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005542posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005543{
5544 PyObject *result = NULL;
5545 int name, fd;
5546
Fred Drake12c6e2d1999-12-14 21:25:03 +00005547 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5548 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005549 long limit;
5550
5551 errno = 0;
5552 limit = fpathconf(fd, name);
5553 if (limit == -1 && errno != 0)
5554 posix_error();
5555 else
5556 result = PyInt_FromLong(limit);
5557 }
5558 return result;
5559}
5560#endif
5561
5562
5563#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005564PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005565"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005566Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005567If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005568
5569static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005570posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005571{
5572 PyObject *result = NULL;
5573 int name;
5574 char *path;
5575
5576 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5577 conv_path_confname, &name)) {
5578 long limit;
5579
5580 errno = 0;
5581 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005582 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005583 if (errno == EINVAL)
5584 /* could be a path or name problem */
5585 posix_error();
5586 else
5587 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005588 }
Fred Drakec9680921999-12-13 16:37:25 +00005589 else
5590 result = PyInt_FromLong(limit);
5591 }
5592 return result;
5593}
5594#endif
5595
5596#ifdef HAVE_CONFSTR
5597static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005598#ifdef _CS_ARCHITECTURE
5599 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5600#endif
5601#ifdef _CS_HOSTNAME
5602 {"CS_HOSTNAME", _CS_HOSTNAME},
5603#endif
5604#ifdef _CS_HW_PROVIDER
5605 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5606#endif
5607#ifdef _CS_HW_SERIAL
5608 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5609#endif
5610#ifdef _CS_INITTAB_NAME
5611 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5612#endif
Fred Drakec9680921999-12-13 16:37:25 +00005613#ifdef _CS_LFS64_CFLAGS
5614 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5615#endif
5616#ifdef _CS_LFS64_LDFLAGS
5617 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5618#endif
5619#ifdef _CS_LFS64_LIBS
5620 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5621#endif
5622#ifdef _CS_LFS64_LINTFLAGS
5623 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5624#endif
5625#ifdef _CS_LFS_CFLAGS
5626 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5627#endif
5628#ifdef _CS_LFS_LDFLAGS
5629 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5630#endif
5631#ifdef _CS_LFS_LIBS
5632 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5633#endif
5634#ifdef _CS_LFS_LINTFLAGS
5635 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5636#endif
Fred Draked86ed291999-12-15 15:34:33 +00005637#ifdef _CS_MACHINE
5638 {"CS_MACHINE", _CS_MACHINE},
5639#endif
Fred Drakec9680921999-12-13 16:37:25 +00005640#ifdef _CS_PATH
5641 {"CS_PATH", _CS_PATH},
5642#endif
Fred Draked86ed291999-12-15 15:34:33 +00005643#ifdef _CS_RELEASE
5644 {"CS_RELEASE", _CS_RELEASE},
5645#endif
5646#ifdef _CS_SRPC_DOMAIN
5647 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5648#endif
5649#ifdef _CS_SYSNAME
5650 {"CS_SYSNAME", _CS_SYSNAME},
5651#endif
5652#ifdef _CS_VERSION
5653 {"CS_VERSION", _CS_VERSION},
5654#endif
Fred Drakec9680921999-12-13 16:37:25 +00005655#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5656 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5657#endif
5658#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5659 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5660#endif
5661#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5662 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5663#endif
5664#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5665 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5666#endif
5667#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5668 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5669#endif
5670#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5671 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5672#endif
5673#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5674 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5675#endif
5676#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5677 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5678#endif
5679#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5680 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5681#endif
5682#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5683 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5684#endif
5685#ifdef _CS_XBS5_LP64_OFF64_LIBS
5686 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5687#endif
5688#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5689 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5690#endif
5691#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5692 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5693#endif
5694#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5695 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5696#endif
5697#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5698 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5699#endif
5700#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5701 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5702#endif
Fred Draked86ed291999-12-15 15:34:33 +00005703#ifdef _MIPS_CS_AVAIL_PROCESSORS
5704 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5705#endif
5706#ifdef _MIPS_CS_BASE
5707 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5708#endif
5709#ifdef _MIPS_CS_HOSTID
5710 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5711#endif
5712#ifdef _MIPS_CS_HW_NAME
5713 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5714#endif
5715#ifdef _MIPS_CS_NUM_PROCESSORS
5716 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5717#endif
5718#ifdef _MIPS_CS_OSREL_MAJ
5719 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5720#endif
5721#ifdef _MIPS_CS_OSREL_MIN
5722 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5723#endif
5724#ifdef _MIPS_CS_OSREL_PATCH
5725 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5726#endif
5727#ifdef _MIPS_CS_OS_NAME
5728 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5729#endif
5730#ifdef _MIPS_CS_OS_PROVIDER
5731 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5732#endif
5733#ifdef _MIPS_CS_PROCESSORS
5734 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5735#endif
5736#ifdef _MIPS_CS_SERIAL
5737 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5738#endif
5739#ifdef _MIPS_CS_VENDOR
5740 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5741#endif
Fred Drakec9680921999-12-13 16:37:25 +00005742};
5743
5744static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005745conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005746{
5747 return conv_confname(arg, valuep, posix_constants_confstr,
5748 sizeof(posix_constants_confstr)
5749 / sizeof(struct constdef));
5750}
5751
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005752PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005753"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005754Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005755
5756static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005757posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005758{
5759 PyObject *result = NULL;
5760 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005761 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00005762
5763 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005764 int len;
Fred Drakec9680921999-12-13 16:37:25 +00005765
Fred Drakec9680921999-12-13 16:37:25 +00005766 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005767 len = confstr(name, buffer, sizeof(buffer));
5768 if (len == 0) {
5769 if (errno) {
5770 posix_error();
5771 }
5772 else {
5773 result = Py_None;
5774 Py_INCREF(Py_None);
5775 }
Fred Drakec9680921999-12-13 16:37:25 +00005776 }
5777 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005778 if ((unsigned int)len >= sizeof(buffer)) {
5779 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00005780 if (result != NULL)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005781 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00005782 }
5783 else
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005784 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00005785 }
5786 }
5787 return result;
5788}
5789#endif
5790
5791
5792#ifdef HAVE_SYSCONF
5793static struct constdef posix_constants_sysconf[] = {
5794#ifdef _SC_2_CHAR_TERM
5795 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5796#endif
5797#ifdef _SC_2_C_BIND
5798 {"SC_2_C_BIND", _SC_2_C_BIND},
5799#endif
5800#ifdef _SC_2_C_DEV
5801 {"SC_2_C_DEV", _SC_2_C_DEV},
5802#endif
5803#ifdef _SC_2_C_VERSION
5804 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5805#endif
5806#ifdef _SC_2_FORT_DEV
5807 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5808#endif
5809#ifdef _SC_2_FORT_RUN
5810 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5811#endif
5812#ifdef _SC_2_LOCALEDEF
5813 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5814#endif
5815#ifdef _SC_2_SW_DEV
5816 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5817#endif
5818#ifdef _SC_2_UPE
5819 {"SC_2_UPE", _SC_2_UPE},
5820#endif
5821#ifdef _SC_2_VERSION
5822 {"SC_2_VERSION", _SC_2_VERSION},
5823#endif
Fred Draked86ed291999-12-15 15:34:33 +00005824#ifdef _SC_ABI_ASYNCHRONOUS_IO
5825 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5826#endif
5827#ifdef _SC_ACL
5828 {"SC_ACL", _SC_ACL},
5829#endif
Fred Drakec9680921999-12-13 16:37:25 +00005830#ifdef _SC_AIO_LISTIO_MAX
5831 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5832#endif
Fred Drakec9680921999-12-13 16:37:25 +00005833#ifdef _SC_AIO_MAX
5834 {"SC_AIO_MAX", _SC_AIO_MAX},
5835#endif
5836#ifdef _SC_AIO_PRIO_DELTA_MAX
5837 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5838#endif
5839#ifdef _SC_ARG_MAX
5840 {"SC_ARG_MAX", _SC_ARG_MAX},
5841#endif
5842#ifdef _SC_ASYNCHRONOUS_IO
5843 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5844#endif
5845#ifdef _SC_ATEXIT_MAX
5846 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5847#endif
Fred Draked86ed291999-12-15 15:34:33 +00005848#ifdef _SC_AUDIT
5849 {"SC_AUDIT", _SC_AUDIT},
5850#endif
Fred Drakec9680921999-12-13 16:37:25 +00005851#ifdef _SC_AVPHYS_PAGES
5852 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5853#endif
5854#ifdef _SC_BC_BASE_MAX
5855 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5856#endif
5857#ifdef _SC_BC_DIM_MAX
5858 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5859#endif
5860#ifdef _SC_BC_SCALE_MAX
5861 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5862#endif
5863#ifdef _SC_BC_STRING_MAX
5864 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5865#endif
Fred Draked86ed291999-12-15 15:34:33 +00005866#ifdef _SC_CAP
5867 {"SC_CAP", _SC_CAP},
5868#endif
Fred Drakec9680921999-12-13 16:37:25 +00005869#ifdef _SC_CHARCLASS_NAME_MAX
5870 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5871#endif
5872#ifdef _SC_CHAR_BIT
5873 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5874#endif
5875#ifdef _SC_CHAR_MAX
5876 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5877#endif
5878#ifdef _SC_CHAR_MIN
5879 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5880#endif
5881#ifdef _SC_CHILD_MAX
5882 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5883#endif
5884#ifdef _SC_CLK_TCK
5885 {"SC_CLK_TCK", _SC_CLK_TCK},
5886#endif
5887#ifdef _SC_COHER_BLKSZ
5888 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5889#endif
5890#ifdef _SC_COLL_WEIGHTS_MAX
5891 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5892#endif
5893#ifdef _SC_DCACHE_ASSOC
5894 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5895#endif
5896#ifdef _SC_DCACHE_BLKSZ
5897 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5898#endif
5899#ifdef _SC_DCACHE_LINESZ
5900 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5901#endif
5902#ifdef _SC_DCACHE_SZ
5903 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5904#endif
5905#ifdef _SC_DCACHE_TBLKSZ
5906 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5907#endif
5908#ifdef _SC_DELAYTIMER_MAX
5909 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5910#endif
5911#ifdef _SC_EQUIV_CLASS_MAX
5912 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5913#endif
5914#ifdef _SC_EXPR_NEST_MAX
5915 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5916#endif
5917#ifdef _SC_FSYNC
5918 {"SC_FSYNC", _SC_FSYNC},
5919#endif
5920#ifdef _SC_GETGR_R_SIZE_MAX
5921 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5922#endif
5923#ifdef _SC_GETPW_R_SIZE_MAX
5924 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5925#endif
5926#ifdef _SC_ICACHE_ASSOC
5927 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5928#endif
5929#ifdef _SC_ICACHE_BLKSZ
5930 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5931#endif
5932#ifdef _SC_ICACHE_LINESZ
5933 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5934#endif
5935#ifdef _SC_ICACHE_SZ
5936 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5937#endif
Fred Draked86ed291999-12-15 15:34:33 +00005938#ifdef _SC_INF
5939 {"SC_INF", _SC_INF},
5940#endif
Fred Drakec9680921999-12-13 16:37:25 +00005941#ifdef _SC_INT_MAX
5942 {"SC_INT_MAX", _SC_INT_MAX},
5943#endif
5944#ifdef _SC_INT_MIN
5945 {"SC_INT_MIN", _SC_INT_MIN},
5946#endif
5947#ifdef _SC_IOV_MAX
5948 {"SC_IOV_MAX", _SC_IOV_MAX},
5949#endif
Fred Draked86ed291999-12-15 15:34:33 +00005950#ifdef _SC_IP_SECOPTS
5951 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5952#endif
Fred Drakec9680921999-12-13 16:37:25 +00005953#ifdef _SC_JOB_CONTROL
5954 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5955#endif
Fred Draked86ed291999-12-15 15:34:33 +00005956#ifdef _SC_KERN_POINTERS
5957 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5958#endif
5959#ifdef _SC_KERN_SIM
5960 {"SC_KERN_SIM", _SC_KERN_SIM},
5961#endif
Fred Drakec9680921999-12-13 16:37:25 +00005962#ifdef _SC_LINE_MAX
5963 {"SC_LINE_MAX", _SC_LINE_MAX},
5964#endif
5965#ifdef _SC_LOGIN_NAME_MAX
5966 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5967#endif
5968#ifdef _SC_LOGNAME_MAX
5969 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5970#endif
5971#ifdef _SC_LONG_BIT
5972 {"SC_LONG_BIT", _SC_LONG_BIT},
5973#endif
Fred Draked86ed291999-12-15 15:34:33 +00005974#ifdef _SC_MAC
5975 {"SC_MAC", _SC_MAC},
5976#endif
Fred Drakec9680921999-12-13 16:37:25 +00005977#ifdef _SC_MAPPED_FILES
5978 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5979#endif
5980#ifdef _SC_MAXPID
5981 {"SC_MAXPID", _SC_MAXPID},
5982#endif
5983#ifdef _SC_MB_LEN_MAX
5984 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5985#endif
5986#ifdef _SC_MEMLOCK
5987 {"SC_MEMLOCK", _SC_MEMLOCK},
5988#endif
5989#ifdef _SC_MEMLOCK_RANGE
5990 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5991#endif
5992#ifdef _SC_MEMORY_PROTECTION
5993 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5994#endif
5995#ifdef _SC_MESSAGE_PASSING
5996 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5997#endif
Fred Draked86ed291999-12-15 15:34:33 +00005998#ifdef _SC_MMAP_FIXED_ALIGNMENT
5999 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6000#endif
Fred Drakec9680921999-12-13 16:37:25 +00006001#ifdef _SC_MQ_OPEN_MAX
6002 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6003#endif
6004#ifdef _SC_MQ_PRIO_MAX
6005 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6006#endif
Fred Draked86ed291999-12-15 15:34:33 +00006007#ifdef _SC_NACLS_MAX
6008 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6009#endif
Fred Drakec9680921999-12-13 16:37:25 +00006010#ifdef _SC_NGROUPS_MAX
6011 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6012#endif
6013#ifdef _SC_NL_ARGMAX
6014 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6015#endif
6016#ifdef _SC_NL_LANGMAX
6017 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6018#endif
6019#ifdef _SC_NL_MSGMAX
6020 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6021#endif
6022#ifdef _SC_NL_NMAX
6023 {"SC_NL_NMAX", _SC_NL_NMAX},
6024#endif
6025#ifdef _SC_NL_SETMAX
6026 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6027#endif
6028#ifdef _SC_NL_TEXTMAX
6029 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6030#endif
6031#ifdef _SC_NPROCESSORS_CONF
6032 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6033#endif
6034#ifdef _SC_NPROCESSORS_ONLN
6035 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6036#endif
Fred Draked86ed291999-12-15 15:34:33 +00006037#ifdef _SC_NPROC_CONF
6038 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6039#endif
6040#ifdef _SC_NPROC_ONLN
6041 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6042#endif
Fred Drakec9680921999-12-13 16:37:25 +00006043#ifdef _SC_NZERO
6044 {"SC_NZERO", _SC_NZERO},
6045#endif
6046#ifdef _SC_OPEN_MAX
6047 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6048#endif
6049#ifdef _SC_PAGESIZE
6050 {"SC_PAGESIZE", _SC_PAGESIZE},
6051#endif
6052#ifdef _SC_PAGE_SIZE
6053 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6054#endif
6055#ifdef _SC_PASS_MAX
6056 {"SC_PASS_MAX", _SC_PASS_MAX},
6057#endif
6058#ifdef _SC_PHYS_PAGES
6059 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6060#endif
6061#ifdef _SC_PII
6062 {"SC_PII", _SC_PII},
6063#endif
6064#ifdef _SC_PII_INTERNET
6065 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6066#endif
6067#ifdef _SC_PII_INTERNET_DGRAM
6068 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6069#endif
6070#ifdef _SC_PII_INTERNET_STREAM
6071 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6072#endif
6073#ifdef _SC_PII_OSI
6074 {"SC_PII_OSI", _SC_PII_OSI},
6075#endif
6076#ifdef _SC_PII_OSI_CLTS
6077 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6078#endif
6079#ifdef _SC_PII_OSI_COTS
6080 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6081#endif
6082#ifdef _SC_PII_OSI_M
6083 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6084#endif
6085#ifdef _SC_PII_SOCKET
6086 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6087#endif
6088#ifdef _SC_PII_XTI
6089 {"SC_PII_XTI", _SC_PII_XTI},
6090#endif
6091#ifdef _SC_POLL
6092 {"SC_POLL", _SC_POLL},
6093#endif
6094#ifdef _SC_PRIORITIZED_IO
6095 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6096#endif
6097#ifdef _SC_PRIORITY_SCHEDULING
6098 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6099#endif
6100#ifdef _SC_REALTIME_SIGNALS
6101 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6102#endif
6103#ifdef _SC_RE_DUP_MAX
6104 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6105#endif
6106#ifdef _SC_RTSIG_MAX
6107 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6108#endif
6109#ifdef _SC_SAVED_IDS
6110 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6111#endif
6112#ifdef _SC_SCHAR_MAX
6113 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6114#endif
6115#ifdef _SC_SCHAR_MIN
6116 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6117#endif
6118#ifdef _SC_SELECT
6119 {"SC_SELECT", _SC_SELECT},
6120#endif
6121#ifdef _SC_SEMAPHORES
6122 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6123#endif
6124#ifdef _SC_SEM_NSEMS_MAX
6125 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6126#endif
6127#ifdef _SC_SEM_VALUE_MAX
6128 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6129#endif
6130#ifdef _SC_SHARED_MEMORY_OBJECTS
6131 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6132#endif
6133#ifdef _SC_SHRT_MAX
6134 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6135#endif
6136#ifdef _SC_SHRT_MIN
6137 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6138#endif
6139#ifdef _SC_SIGQUEUE_MAX
6140 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6141#endif
6142#ifdef _SC_SIGRT_MAX
6143 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6144#endif
6145#ifdef _SC_SIGRT_MIN
6146 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6147#endif
Fred Draked86ed291999-12-15 15:34:33 +00006148#ifdef _SC_SOFTPOWER
6149 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6150#endif
Fred Drakec9680921999-12-13 16:37:25 +00006151#ifdef _SC_SPLIT_CACHE
6152 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6153#endif
6154#ifdef _SC_SSIZE_MAX
6155 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6156#endif
6157#ifdef _SC_STACK_PROT
6158 {"SC_STACK_PROT", _SC_STACK_PROT},
6159#endif
6160#ifdef _SC_STREAM_MAX
6161 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6162#endif
6163#ifdef _SC_SYNCHRONIZED_IO
6164 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6165#endif
6166#ifdef _SC_THREADS
6167 {"SC_THREADS", _SC_THREADS},
6168#endif
6169#ifdef _SC_THREAD_ATTR_STACKADDR
6170 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6171#endif
6172#ifdef _SC_THREAD_ATTR_STACKSIZE
6173 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6174#endif
6175#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6176 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6177#endif
6178#ifdef _SC_THREAD_KEYS_MAX
6179 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6180#endif
6181#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6182 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6183#endif
6184#ifdef _SC_THREAD_PRIO_INHERIT
6185 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6186#endif
6187#ifdef _SC_THREAD_PRIO_PROTECT
6188 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6189#endif
6190#ifdef _SC_THREAD_PROCESS_SHARED
6191 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6192#endif
6193#ifdef _SC_THREAD_SAFE_FUNCTIONS
6194 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6195#endif
6196#ifdef _SC_THREAD_STACK_MIN
6197 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6198#endif
6199#ifdef _SC_THREAD_THREADS_MAX
6200 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6201#endif
6202#ifdef _SC_TIMERS
6203 {"SC_TIMERS", _SC_TIMERS},
6204#endif
6205#ifdef _SC_TIMER_MAX
6206 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6207#endif
6208#ifdef _SC_TTY_NAME_MAX
6209 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6210#endif
6211#ifdef _SC_TZNAME_MAX
6212 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6213#endif
6214#ifdef _SC_T_IOV_MAX
6215 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6216#endif
6217#ifdef _SC_UCHAR_MAX
6218 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6219#endif
6220#ifdef _SC_UINT_MAX
6221 {"SC_UINT_MAX", _SC_UINT_MAX},
6222#endif
6223#ifdef _SC_UIO_MAXIOV
6224 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6225#endif
6226#ifdef _SC_ULONG_MAX
6227 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6228#endif
6229#ifdef _SC_USHRT_MAX
6230 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6231#endif
6232#ifdef _SC_VERSION
6233 {"SC_VERSION", _SC_VERSION},
6234#endif
6235#ifdef _SC_WORD_BIT
6236 {"SC_WORD_BIT", _SC_WORD_BIT},
6237#endif
6238#ifdef _SC_XBS5_ILP32_OFF32
6239 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6240#endif
6241#ifdef _SC_XBS5_ILP32_OFFBIG
6242 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6243#endif
6244#ifdef _SC_XBS5_LP64_OFF64
6245 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6246#endif
6247#ifdef _SC_XBS5_LPBIG_OFFBIG
6248 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6249#endif
6250#ifdef _SC_XOPEN_CRYPT
6251 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6252#endif
6253#ifdef _SC_XOPEN_ENH_I18N
6254 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6255#endif
6256#ifdef _SC_XOPEN_LEGACY
6257 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6258#endif
6259#ifdef _SC_XOPEN_REALTIME
6260 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6261#endif
6262#ifdef _SC_XOPEN_REALTIME_THREADS
6263 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6264#endif
6265#ifdef _SC_XOPEN_SHM
6266 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6267#endif
6268#ifdef _SC_XOPEN_UNIX
6269 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6270#endif
6271#ifdef _SC_XOPEN_VERSION
6272 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6273#endif
6274#ifdef _SC_XOPEN_XCU_VERSION
6275 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6276#endif
6277#ifdef _SC_XOPEN_XPG2
6278 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6279#endif
6280#ifdef _SC_XOPEN_XPG3
6281 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6282#endif
6283#ifdef _SC_XOPEN_XPG4
6284 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6285#endif
6286};
6287
6288static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006289conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006290{
6291 return conv_confname(arg, valuep, posix_constants_sysconf,
6292 sizeof(posix_constants_sysconf)
6293 / sizeof(struct constdef));
6294}
6295
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006296PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006297"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006298Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006299
6300static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006301posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006302{
6303 PyObject *result = NULL;
6304 int name;
6305
6306 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6307 int value;
6308
6309 errno = 0;
6310 value = sysconf(name);
6311 if (value == -1 && errno != 0)
6312 posix_error();
6313 else
6314 result = PyInt_FromLong(value);
6315 }
6316 return result;
6317}
6318#endif
6319
6320
Fred Drakebec628d1999-12-15 18:31:10 +00006321/* This code is used to ensure that the tables of configuration value names
6322 * are in sorted order as required by conv_confname(), and also to build the
6323 * the exported dictionaries that are used to publish information about the
6324 * names available on the host platform.
6325 *
6326 * Sorting the table at runtime ensures that the table is properly ordered
6327 * when used, even for platforms we're not able to test on. It also makes
6328 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006329 */
Fred Drakebec628d1999-12-15 18:31:10 +00006330
6331static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006332cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006333{
6334 const struct constdef *c1 =
6335 (const struct constdef *) v1;
6336 const struct constdef *c2 =
6337 (const struct constdef *) v2;
6338
6339 return strcmp(c1->name, c2->name);
6340}
6341
6342static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006343setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006344 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006345{
Fred Drakebec628d1999-12-15 18:31:10 +00006346 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006347 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006348
6349 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6350 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006351 if (d == NULL)
6352 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006353
Barry Warsaw3155db32000-04-13 15:20:40 +00006354 for (i=0; i < tablesize; ++i) {
6355 PyObject *o = PyInt_FromLong(table[i].value);
6356 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6357 Py_XDECREF(o);
6358 Py_DECREF(d);
6359 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006360 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006361 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006362 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006363 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006364}
6365
Fred Drakebec628d1999-12-15 18:31:10 +00006366/* Return -1 on failure, 0 on success. */
6367static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006368setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006369{
6370#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006371 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006372 sizeof(posix_constants_pathconf)
6373 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006374 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006375 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006376#endif
6377#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006378 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006379 sizeof(posix_constants_confstr)
6380 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006381 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006382 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006383#endif
6384#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006385 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006386 sizeof(posix_constants_sysconf)
6387 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006388 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006389 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006390#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006391 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006392}
Fred Draked86ed291999-12-15 15:34:33 +00006393
6394
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006395PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006396"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006397Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006398in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006399
6400static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006401posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006402{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006403 abort();
6404 /*NOTREACHED*/
6405 Py_FatalError("abort() called from Python code didn't abort!");
6406 return NULL;
6407}
Fred Drakebec628d1999-12-15 18:31:10 +00006408
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006409#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006410PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00006411"startfile(filepath [, operation]) - Start a file with its associated\n\
6412application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006413\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00006414When \"operation\" is not specified or \"open\", this acts like\n\
6415double-clicking the file in Explorer, or giving the file name as an\n\
6416argument to the DOS \"start\" command: the file is opened with whatever\n\
6417application (if any) its extension is associated.\n\
6418When another \"operation\" is given, it specifies what should be done with\n\
6419the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006420\n\
6421startfile returns as soon as the associated application is launched.\n\
6422There is no option to wait for the application to close, and no way\n\
6423to retrieve the application's exit status.\n\
6424\n\
6425The filepath is relative to the current directory. If you want to use\n\
6426an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006427the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006428
6429static PyObject *
6430win32_startfile(PyObject *self, PyObject *args)
6431{
6432 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00006433 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006434 HINSTANCE rc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006435#ifdef Py_WIN_WIDE_FILENAMES
6436 if (unicode_file_names()) {
6437 PyObject *unipath, *woperation = NULL;
6438 if (!PyArg_ParseTuple(args, "U|s:startfile",
6439 &unipath, &operation)) {
6440 PyErr_Clear();
6441 goto normal;
6442 }
6443
6444
6445 if (operation) {
6446 woperation = PyUnicode_DecodeASCII(operation,
6447 strlen(operation), NULL);
6448 if (!woperation) {
6449 PyErr_Clear();
6450 operation = NULL;
6451 goto normal;
6452 }
6453 }
6454
6455 Py_BEGIN_ALLOW_THREADS
6456 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6457 PyUnicode_AS_UNICODE(unipath),
6458 NULL, NULL, SW_SHOWNORMAL);
6459 Py_END_ALLOW_THREADS
6460
6461 Py_XDECREF(woperation);
6462 if (rc <= (HINSTANCE)32) {
6463 PyObject *errval = win32_error_unicode("startfile",
6464 PyUnicode_AS_UNICODE(unipath));
6465 return errval;
6466 }
6467 Py_INCREF(Py_None);
6468 return Py_None;
6469 }
6470#endif
6471
6472normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00006473 if (!PyArg_ParseTuple(args, "et|s:startfile",
6474 Py_FileSystemDefaultEncoding, &filepath,
6475 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00006476 return NULL;
6477 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00006478 rc = ShellExecute((HWND)0, operation, filepath,
6479 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006480 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00006481 if (rc <= (HINSTANCE)32) {
6482 PyObject *errval = win32_error("startfile", filepath);
6483 PyMem_Free(filepath);
6484 return errval;
6485 }
6486 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006487 Py_INCREF(Py_None);
6488 return Py_None;
6489}
6490#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006491
Martin v. Löwis438b5342002-12-27 10:16:42 +00006492#ifdef HAVE_GETLOADAVG
6493PyDoc_STRVAR(posix_getloadavg__doc__,
6494"getloadavg() -> (float, float, float)\n\n\
6495Return the number of processes in the system run queue averaged over\n\
6496the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6497was unobtainable");
6498
6499static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006500posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006501{
6502 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006503 if (getloadavg(loadavg, 3)!=3) {
6504 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6505 return NULL;
6506 } else
6507 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6508}
6509#endif
6510
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006511#ifdef MS_WINDOWS
6512
6513PyDoc_STRVAR(win32_urandom__doc__,
6514"urandom(n) -> str\n\n\
6515Return a string of n random bytes suitable for cryptographic use.");
6516
6517typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6518 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6519 DWORD dwFlags );
6520typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6521 BYTE *pbBuffer );
6522
6523static CRYPTGENRANDOM pCryptGenRandom = NULL;
6524static HCRYPTPROV hCryptProv = 0;
6525
Tim Peters4ad82172004-08-30 17:02:04 +00006526static PyObject*
6527win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006528{
Tim Petersd3115382004-08-30 17:36:46 +00006529 int howMany;
6530 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006531
Tim Peters4ad82172004-08-30 17:02:04 +00006532 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00006533 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00006534 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00006535 if (howMany < 0)
6536 return PyErr_Format(PyExc_ValueError,
6537 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006538
Tim Peters4ad82172004-08-30 17:02:04 +00006539 if (hCryptProv == 0) {
6540 HINSTANCE hAdvAPI32 = NULL;
6541 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006542
Tim Peters4ad82172004-08-30 17:02:04 +00006543 /* Obtain handle to the DLL containing CryptoAPI
6544 This should not fail */
6545 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6546 if(hAdvAPI32 == NULL)
6547 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006548
Tim Peters4ad82172004-08-30 17:02:04 +00006549 /* Obtain pointers to the CryptoAPI functions
6550 This will fail on some early versions of Win95 */
6551 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6552 hAdvAPI32,
6553 "CryptAcquireContextA");
6554 if (pCryptAcquireContext == NULL)
6555 return PyErr_Format(PyExc_NotImplementedError,
6556 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006557
Tim Peters4ad82172004-08-30 17:02:04 +00006558 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6559 hAdvAPI32, "CryptGenRandom");
Thomas Wouters89f507f2006-12-13 04:49:30 +00006560 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00006561 return PyErr_Format(PyExc_NotImplementedError,
6562 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006563
Tim Peters4ad82172004-08-30 17:02:04 +00006564 /* Acquire context */
6565 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
6566 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
6567 return win32_error("CryptAcquireContext", NULL);
6568 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006569
Tim Peters4ad82172004-08-30 17:02:04 +00006570 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00006571 result = PyString_FromStringAndSize(NULL, howMany);
6572 if (result != NULL) {
6573 /* Get random data */
6574 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
6575 PyString_AS_STRING(result))) {
6576 Py_DECREF(result);
6577 return win32_error("CryptGenRandom", NULL);
6578 }
Tim Peters4ad82172004-08-30 17:02:04 +00006579 }
Tim Petersd3115382004-08-30 17:36:46 +00006580 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006581}
6582#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00006583
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006584#ifdef __VMS
6585/* Use openssl random routine */
6586#include <openssl/rand.h>
6587PyDoc_STRVAR(vms_urandom__doc__,
6588"urandom(n) -> str\n\n\
6589Return a string of n random bytes suitable for cryptographic use.");
6590
6591static PyObject*
6592vms_urandom(PyObject *self, PyObject *args)
6593{
6594 int howMany;
6595 PyObject* result;
6596
6597 /* Read arguments */
6598 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
6599 return NULL;
6600 if (howMany < 0)
6601 return PyErr_Format(PyExc_ValueError,
6602 "negative argument not allowed");
6603
6604 /* Allocate bytes */
6605 result = PyString_FromStringAndSize(NULL, howMany);
6606 if (result != NULL) {
6607 /* Get random data */
6608 if (RAND_pseudo_bytes((unsigned char*)
6609 PyString_AS_STRING(result),
6610 howMany) < 0) {
6611 Py_DECREF(result);
6612 return PyErr_Format(PyExc_ValueError,
6613 "RAND_pseudo_bytes");
6614 }
6615 }
6616 return result;
6617}
6618#endif
6619
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006620static PyMethodDef posix_methods[] = {
6621 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6622#ifdef HAVE_TTYNAME
6623 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6624#endif
6625 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00006626#ifdef HAVE_CHFLAGS
6627 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
6628#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006629 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006630#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006631 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006632#endif /* HAVE_CHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00006633#ifdef HAVE_LCHFLAGS
6634 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
6635#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006636#ifdef HAVE_LCHOWN
6637 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6638#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006639#ifdef HAVE_CHROOT
6640 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6641#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006642#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006643 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006644#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006645#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00006646 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Neal Norwitze241ce82003-02-17 18:17:05 +00006647 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006648#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006649#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006650 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006651#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006652 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6653 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6654 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006655#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006656 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006657#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006658#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006659 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006660#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006661 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6662 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6663 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006664 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006665#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006666 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006667#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006668#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006669 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006670#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006671 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006672#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00006673 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006674#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006675 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6676 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6677 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006678#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00006679 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006680#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006681 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006682#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006683 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6684 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006685#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006686#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006687 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6688 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006689#if defined(PYOS_OS2)
6690 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
6691 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
6692#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00006693#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006694#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00006695 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006696#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006697#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00006698 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006699#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006700#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00006701 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006702#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006703#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00006704 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00006705#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006706#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006707 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006708#endif /* HAVE_GETEGID */
6709#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006710 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006711#endif /* HAVE_GETEUID */
6712#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006713 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006714#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006715#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00006716 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00006717#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00006718 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006719#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006720 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006721#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006722#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00006723 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006724#endif /* HAVE_GETPPID */
6725#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006726 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006727#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006728#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00006729 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00006730#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006731#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006732 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006733#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006734#ifdef HAVE_KILLPG
6735 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6736#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006737#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006738 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006739#endif /* HAVE_PLOCK */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006740#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006741 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006742#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006743#ifdef HAVE_SETEUID
6744 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6745#endif /* HAVE_SETEUID */
6746#ifdef HAVE_SETEGID
6747 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6748#endif /* HAVE_SETEGID */
6749#ifdef HAVE_SETREUID
6750 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6751#endif /* HAVE_SETREUID */
6752#ifdef HAVE_SETREGID
6753 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6754#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006755#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006756 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006757#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006758#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006759 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006760#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006761#ifdef HAVE_GETPGID
6762 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6763#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006764#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006765 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006766#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006767#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00006768 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006769#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006770#ifdef HAVE_WAIT3
6771 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
6772#endif /* HAVE_WAIT3 */
6773#ifdef HAVE_WAIT4
6774 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
6775#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00006776#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006777 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006778#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006779#ifdef HAVE_GETSID
6780 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
6781#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006782#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00006783 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006784#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006785#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006786 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006787#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006788#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006789 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006790#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006791#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006792 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006793#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006794 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6795 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6796 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6797 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6798 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6799 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6800 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6801 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006802 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006803#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00006804 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006805#endif
6806#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006807 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006808#endif
Neal Norwitz11690112002-07-30 01:08:28 +00006809#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006810 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6811#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006812#ifdef HAVE_DEVICE_MACROS
6813 {"major", posix_major, METH_VARARGS, posix_major__doc__},
6814 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
6815 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
6816#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006817#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006818 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006819#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006820#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006821 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006822#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006823#ifdef HAVE_UNSETENV
6824 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6825#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006826#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006827 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006828#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006829#ifdef HAVE_FCHDIR
6830 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6831#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006832#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006833 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006834#endif
6835#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006836 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006837#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006838#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006839#ifdef WCOREDUMP
6840 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6841#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006842#ifdef WIFCONTINUED
6843 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6844#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006845#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006846 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006847#endif /* WIFSTOPPED */
6848#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006849 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006850#endif /* WIFSIGNALED */
6851#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006852 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006853#endif /* WIFEXITED */
6854#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006855 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006856#endif /* WEXITSTATUS */
6857#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006858 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006859#endif /* WTERMSIG */
6860#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006861 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006862#endif /* WSTOPSIG */
6863#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00006864#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006865 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006866#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00006867#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006868 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006869#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006870#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00006871 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006872#endif
6873#ifdef HAVE_TEMPNAM
6874 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6875#endif
6876#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00006877 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006878#endif
Fred Drakec9680921999-12-13 16:37:25 +00006879#ifdef HAVE_CONFSTR
6880 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6881#endif
6882#ifdef HAVE_SYSCONF
6883 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6884#endif
6885#ifdef HAVE_FPATHCONF
6886 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6887#endif
6888#ifdef HAVE_PATHCONF
6889 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6890#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00006891 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006892#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00006893 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6894#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00006895#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00006896 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00006897#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006898 #ifdef MS_WINDOWS
6899 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
6900 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006901 #ifdef __VMS
6902 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
6903 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006904 {NULL, NULL} /* Sentinel */
6905};
6906
6907
Barry Warsaw4a342091996-12-19 23:50:02 +00006908static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006909ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006910{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006911 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006912}
6913
Guido van Rossumd48f2521997-12-05 22:19:34 +00006914#if defined(PYOS_OS2)
6915/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006916static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006917{
6918 APIRET rc;
6919 ULONG values[QSV_MAX+1];
6920 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006921 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006922
6923 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00006924 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006925 Py_END_ALLOW_THREADS
6926
6927 if (rc != NO_ERROR) {
6928 os2_error(rc);
6929 return -1;
6930 }
6931
Fred Drake4d1e64b2002-04-15 19:40:07 +00006932 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6933 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6934 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6935 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6936 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6937 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6938 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006939
6940 switch (values[QSV_VERSION_MINOR]) {
6941 case 0: ver = "2.00"; break;
6942 case 10: ver = "2.10"; break;
6943 case 11: ver = "2.11"; break;
6944 case 30: ver = "3.00"; break;
6945 case 40: ver = "4.00"; break;
6946 case 50: ver = "5.00"; break;
6947 default:
Tim Peters885d4572001-11-28 20:27:42 +00006948 PyOS_snprintf(tmp, sizeof(tmp),
6949 "%d-%d", values[QSV_VERSION_MAJOR],
6950 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006951 ver = &tmp[0];
6952 }
6953
6954 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006955 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006956 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006957
6958 /* Add Indicator of Which Drive was Used to Boot the System */
6959 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6960 tmp[1] = ':';
6961 tmp[2] = '\0';
6962
Fred Drake4d1e64b2002-04-15 19:40:07 +00006963 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006964}
6965#endif
6966
Barry Warsaw4a342091996-12-19 23:50:02 +00006967static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006968all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006969{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006970#ifdef F_OK
6971 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006972#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006973#ifdef R_OK
6974 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006975#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006976#ifdef W_OK
6977 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006978#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006979#ifdef X_OK
6980 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006981#endif
Fred Drakec9680921999-12-13 16:37:25 +00006982#ifdef NGROUPS_MAX
6983 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6984#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006985#ifdef TMP_MAX
6986 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6987#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006988#ifdef WCONTINUED
6989 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
6990#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006991#ifdef WNOHANG
6992 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006993#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006994#ifdef WUNTRACED
6995 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
6996#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006997#ifdef O_RDONLY
6998 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6999#endif
7000#ifdef O_WRONLY
7001 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7002#endif
7003#ifdef O_RDWR
7004 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7005#endif
7006#ifdef O_NDELAY
7007 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7008#endif
7009#ifdef O_NONBLOCK
7010 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7011#endif
7012#ifdef O_APPEND
7013 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7014#endif
7015#ifdef O_DSYNC
7016 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7017#endif
7018#ifdef O_RSYNC
7019 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7020#endif
7021#ifdef O_SYNC
7022 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7023#endif
7024#ifdef O_NOCTTY
7025 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7026#endif
7027#ifdef O_CREAT
7028 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7029#endif
7030#ifdef O_EXCL
7031 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7032#endif
7033#ifdef O_TRUNC
7034 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7035#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007036#ifdef O_BINARY
7037 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7038#endif
7039#ifdef O_TEXT
7040 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7041#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007042#ifdef O_LARGEFILE
7043 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7044#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007045#ifdef O_SHLOCK
7046 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7047#endif
7048#ifdef O_EXLOCK
7049 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7050#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007051
Tim Peters5aa91602002-01-30 05:46:57 +00007052/* MS Windows */
7053#ifdef O_NOINHERIT
7054 /* Don't inherit in child processes. */
7055 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7056#endif
7057#ifdef _O_SHORT_LIVED
7058 /* Optimize for short life (keep in memory). */
7059 /* MS forgot to define this one with a non-underscore form too. */
7060 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7061#endif
7062#ifdef O_TEMPORARY
7063 /* Automatically delete when last handle is closed. */
7064 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7065#endif
7066#ifdef O_RANDOM
7067 /* Optimize for random access. */
7068 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7069#endif
7070#ifdef O_SEQUENTIAL
7071 /* Optimize for sequential access. */
7072 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7073#endif
7074
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007075/* GNU extensions. */
7076#ifdef O_DIRECT
7077 /* Direct disk access. */
7078 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7079#endif
7080#ifdef O_DIRECTORY
7081 /* Must be a directory. */
7082 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7083#endif
7084#ifdef O_NOFOLLOW
7085 /* Do not follow links. */
7086 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7087#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007088
Barry Warsaw5676bd12003-01-07 20:57:09 +00007089 /* These come from sysexits.h */
7090#ifdef EX_OK
7091 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007092#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007093#ifdef EX_USAGE
7094 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007095#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007096#ifdef EX_DATAERR
7097 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007098#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007099#ifdef EX_NOINPUT
7100 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007101#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007102#ifdef EX_NOUSER
7103 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007104#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007105#ifdef EX_NOHOST
7106 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007107#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007108#ifdef EX_UNAVAILABLE
7109 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007110#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007111#ifdef EX_SOFTWARE
7112 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007113#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007114#ifdef EX_OSERR
7115 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007116#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007117#ifdef EX_OSFILE
7118 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007119#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007120#ifdef EX_CANTCREAT
7121 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007122#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007123#ifdef EX_IOERR
7124 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007125#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007126#ifdef EX_TEMPFAIL
7127 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007128#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007129#ifdef EX_PROTOCOL
7130 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007131#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007132#ifdef EX_NOPERM
7133 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007134#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007135#ifdef EX_CONFIG
7136 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007137#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007138#ifdef EX_NOTFOUND
7139 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007140#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007141
Guido van Rossum246bc171999-02-01 23:54:31 +00007142#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007143#if defined(PYOS_OS2) && defined(PYCC_GCC)
7144 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7145 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7146 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7147 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7148 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7149 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7150 if (ins(d, "P_PM", (long)P_PM)) return -1;
7151 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7152 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7153 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7154 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7155 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7156 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7157 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7158 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7159 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7160 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7161 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7162 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7163 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7164#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007165 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7166 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7167 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7168 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7169 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007170#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007171#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007172
Guido van Rossumd48f2521997-12-05 22:19:34 +00007173#if defined(PYOS_OS2)
7174 if (insertvalues(d)) return -1;
7175#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007176 return 0;
7177}
7178
7179
Tim Peters5aa91602002-01-30 05:46:57 +00007180#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007181#define INITFUNC initnt
7182#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007183
7184#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007185#define INITFUNC initos2
7186#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007187
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007188#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007189#define INITFUNC initposix
7190#define MODNAME "posix"
7191#endif
7192
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007193PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007194INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007195{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007196 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007197
Fred Drake4d1e64b2002-04-15 19:40:07 +00007198 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007199 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007200 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00007201 if (m == NULL)
7202 return;
Tim Peters5aa91602002-01-30 05:46:57 +00007203
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007204 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007205 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007206 Py_XINCREF(v);
7207 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007208 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007209 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007210
Fred Drake4d1e64b2002-04-15 19:40:07 +00007211 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007212 return;
7213
Fred Drake4d1e64b2002-04-15 19:40:07 +00007214 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007215 return;
7216
Fred Drake4d1e64b2002-04-15 19:40:07 +00007217 Py_INCREF(PyExc_OSError);
7218 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007219
Guido van Rossumb3d39562000-01-31 18:41:26 +00007220#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007221 if (posix_putenv_garbage == NULL)
7222 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007223#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007224
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007225 if (!initialized) {
7226 stat_result_desc.name = MODNAME ".stat_result";
7227 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7228 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7229 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7230 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7231 structseq_new = StatResultType.tp_new;
7232 StatResultType.tp_new = statresult_new;
7233
7234 statvfs_result_desc.name = MODNAME ".statvfs_result";
7235 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
7236 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007237 Py_INCREF((PyObject*) &StatResultType);
7238 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007239 Py_INCREF((PyObject*) &StatVFSResultType);
7240 PyModule_AddObject(m, "statvfs_result",
7241 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007242 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007243
7244#ifdef __APPLE__
7245 /*
7246 * Step 2 of weak-linking support on Mac OS X.
7247 *
7248 * The code below removes functions that are not available on the
7249 * currently active platform.
7250 *
7251 * This block allow one to use a python binary that was build on
7252 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7253 * OSX 10.4.
7254 */
7255#ifdef HAVE_FSTATVFS
7256 if (fstatvfs == NULL) {
7257 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
7258 return;
7259 }
7260 }
7261#endif /* HAVE_FSTATVFS */
7262
7263#ifdef HAVE_STATVFS
7264 if (statvfs == NULL) {
7265 if (PyObject_DelAttrString(m, "statvfs") == -1) {
7266 return;
7267 }
7268 }
7269#endif /* HAVE_STATVFS */
7270
7271# ifdef HAVE_LCHOWN
7272 if (lchown == NULL) {
7273 if (PyObject_DelAttrString(m, "lchown") == -1) {
7274 return;
7275 }
7276 }
7277#endif /* HAVE_LCHOWN */
7278
7279
7280#endif /* __APPLE__ */
7281
Guido van Rossumb6775db1994-08-01 11:34:53 +00007282}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007283
7284#ifdef __cplusplus
7285}
7286#endif