blob: 03959f733fc18fb140f1d00018da81708be58a96 [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
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000095#ifdef HAVE_LANGINFO_H
96#include <langinfo.h>
97#endif
98
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000100/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#include <process.h>
103#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000104#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#define HAVE_GETCWD 1
106#define HAVE_OPENDIR 1
107#define HAVE_SYSTEM 1
108#if defined(__OS2__)
109#define HAVE_EXECV 1
110#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#include <process.h>
113#else
114#ifdef __BORLANDC__ /* Borland compiler */
115#define HAVE_EXECV 1
116#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_OPENDIR 1
118#define HAVE_PIPE 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000119#define HAVE_SYSTEM 1
120#define HAVE_WAIT 1
121#else
122#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000123#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000124#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000125#define HAVE_EXECV 1
126#define HAVE_PIPE 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000127#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000128#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000129#define HAVE_FSYNC 1
130#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000131#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000132#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
133/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134#else /* all other compilers */
135/* Unix functions that the configure script doesn't check for */
136#define HAVE_EXECV 1
137#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000138#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
139#define HAVE_FORK1 1
140#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#define HAVE_GETCWD 1
142#define HAVE_GETEGID 1
143#define HAVE_GETEUID 1
144#define HAVE_GETGID 1
145#define HAVE_GETPPID 1
146#define HAVE_GETUID 1
147#define HAVE_KILL 1
148#define HAVE_OPENDIR 1
149#define HAVE_PIPE 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000150#define HAVE_SYSTEM 1
151#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000152#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000153#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000154#endif /* _MSC_VER */
155#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000156#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000157#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000158
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000160
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000161#if defined(__sgi)&&_COMPILER_VERSION>=700
162/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
163 (default) */
164extern char *ctermid_r(char *);
165#endif
166
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000167#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000168#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000170#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000171#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000176#endif
177#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000178extern int chdir(char *);
179extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000180#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000181extern int chdir(const char *);
182extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000183#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000184#ifdef __BORLANDC__
185extern int chmod(const char *, int);
186#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000187extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000188#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000189/*#ifdef HAVE_FCHMOD
190extern int fchmod(int, mode_t);
191#endif*/
192/*#ifdef HAVE_LCHMOD
193extern int lchmod(const char *, mode_t);
194#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000195extern int chown(const char *, uid_t, gid_t);
196extern char *getcwd(char *, int);
197extern char *strerror(int);
198extern int link(const char *, const char *);
199extern int rename(const char *, const char *);
200extern int stat(const char *, struct stat *);
201extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000204#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000207#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000209
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000210#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#ifdef HAVE_UTIME_H
213#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000214#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000216#ifdef HAVE_SYS_UTIME_H
217#include <sys/utime.h>
218#define HAVE_UTIME_H /* pretend we do for the rest of this file */
219#endif /* HAVE_SYS_UTIME_H */
220
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#ifdef HAVE_SYS_TIMES_H
222#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000223#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
225#ifdef HAVE_SYS_PARAM_H
226#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000227#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228
229#ifdef HAVE_SYS_UTSNAME_H
230#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000231#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000233#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#define NAMLEN(dirent) strlen((dirent)->d_name)
236#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000237#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#include <direct.h>
239#define NAMLEN(dirent) strlen((dirent)->d_name)
240#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000243#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#endif
247#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000249#endif
250#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000252#endif
253#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000255#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000256#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000258#endif
259#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000261#endif
262#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000264#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000265#include "osdefs.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000267#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000268#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269
Guido van Rossumd48f2521997-12-05 22:19:34 +0000270#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000272#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000273
Tim Petersbc2e10e2002-03-03 23:17:02 +0000274#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000275#if defined(PATH_MAX) && PATH_MAX > 1024
276#define MAXPATHLEN PATH_MAX
277#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000278#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000279#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000280#endif /* MAXPATHLEN */
281
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000282#ifdef UNION_WAIT
283/* Emulate some macros on systems that have a union instead of macros */
284
285#ifndef WIFEXITED
286#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
287#endif
288
289#ifndef WEXITSTATUS
290#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
291#endif
292
293#ifndef WTERMSIG
294#define WTERMSIG(u_wait) ((u_wait).w_termsig)
295#endif
296
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000297#define WAIT_TYPE union wait
298#define WAIT_STATUS_INT(s) (s.w_status)
299
300#else /* !UNION_WAIT */
301#define WAIT_TYPE int
302#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000303#endif /* UNION_WAIT */
304
Greg Wardb48bc172000-03-01 21:51:56 +0000305/* Don't use the "_r" form if we don't need it (also, won't have a
306 prototype for it, at least on Solaris -- maybe others as well?). */
307#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
308#define USE_CTERMID_R
309#endif
310
Fred Drake699f3522000-06-29 21:12:41 +0000311/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000312#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000313#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000314# define STAT win32_stat
315# define FSTAT win32_fstat
316# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000317#else
318# define STAT stat
319# define FSTAT fstat
320# define STRUCT_STAT struct stat
321#endif
322
Tim Peters11b23062003-04-23 02:39:17 +0000323#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000324#include <sys/mkdev.h>
325#else
326#if defined(MAJOR_IN_SYSMACROS)
327#include <sys/sysmacros.h>
328#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000329#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
330#include <sys/mkdev.h>
331#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000332#endif
Fred Drake699f3522000-06-29 21:12:41 +0000333
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000334/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000335#ifdef WITH_NEXT_FRAMEWORK
336/* On Darwin/MacOSX a shared library or framework has no access to
337** environ directly, we must obtain it with _NSGetEnviron().
338*/
339#include <crt_externs.h>
340static char **environ;
341#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000342extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000343#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000344
Barry Warsaw53699e91996-12-10 23:23:01 +0000345static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000346convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000347{
Barry Warsaw53699e91996-12-10 23:23:01 +0000348 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000349#ifdef MS_WINDOWS
350 wchar_t **e;
351#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000352 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000353#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000354 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000355 if (d == NULL)
356 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000357#ifdef WITH_NEXT_FRAMEWORK
358 if (environ == NULL)
359 environ = *_NSGetEnviron();
360#endif
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000361#ifdef MS_WINDOWS
362 /* _wenviron must be initialized in this way if the program is started
363 through main() instead of wmain(). */
364 _wgetenv(L"");
365 if (_wenviron == NULL)
366 return d;
367 /* This part ignores errors */
368 for (e = _wenviron; *e != NULL; e++) {
369 PyObject *k;
370 PyObject *v;
371 wchar_t *p = wcschr(*e, L'=');
372 if (p == NULL)
373 continue;
374 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
375 if (k == NULL) {
376 PyErr_Clear();
377 continue;
378 }
379 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
380 if (v == NULL) {
381 PyErr_Clear();
382 Py_DECREF(k);
383 continue;
384 }
385 if (PyDict_GetItem(d, k) == NULL) {
386 if (PyDict_SetItem(d, k, v) != 0)
387 PyErr_Clear();
388 }
389 Py_DECREF(k);
390 Py_DECREF(v);
391 }
392#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000393 if (environ == NULL)
394 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000395 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000396 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000397 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000398 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000399 char *p = strchr(*e, '=');
400 if (p == NULL)
401 continue;
Guido van Rossum98297ee2007-11-06 21:34:58 +0000402 k = PyUnicode_FromStringAndSize(*e, (int)(p-*e));
Guido van Rossum6a619f41999-08-03 19:41:10 +0000403 if (k == NULL) {
404 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000405 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000406 }
Guido van Rossum98297ee2007-11-06 21:34:58 +0000407 v = PyUnicode_FromString(p+1);
Guido van Rossum6a619f41999-08-03 19:41:10 +0000408 if (v == NULL) {
409 PyErr_Clear();
410 Py_DECREF(k);
411 continue;
412 }
413 if (PyDict_GetItem(d, k) == NULL) {
414 if (PyDict_SetItem(d, k, v) != 0)
415 PyErr_Clear();
416 }
417 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000418 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000419 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000420#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000421#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000422 {
423 APIRET rc;
424 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
425
426 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000427 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Christian Heimes72b710a2008-05-26 13:28:38 +0000428 PyObject *v = PyBytes_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000429 PyDict_SetItemString(d, "BEGINLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000430 Py_DECREF(v);
431 }
432 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
433 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
Christian Heimes72b710a2008-05-26 13:28:38 +0000434 PyObject *v = PyBytes_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000435 PyDict_SetItemString(d, "ENDLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000436 Py_DECREF(v);
437 }
438 }
439#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000440 return d;
441}
442
443
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000444/* Set a POSIX-specific error from errno, and return NULL */
445
Barry Warsawd58d7641998-07-23 16:14:40 +0000446static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000447posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000448{
Barry Warsawca74da41999-02-09 19:31:45 +0000449 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000450}
Barry Warsawd58d7641998-07-23 16:14:40 +0000451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000452posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000453{
Barry Warsawca74da41999-02-09 19:31:45 +0000454 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000455}
456
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000457#ifdef Py_WIN_WIDE_FILENAMES
458static PyObject *
459posix_error_with_unicode_filename(Py_UNICODE* name)
460{
461 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
462}
463#endif /* Py_WIN_WIDE_FILENAMES */
464
465
Mark Hammondef8b6542001-05-13 08:04:26 +0000466static PyObject *
467posix_error_with_allocated_filename(char* name)
468{
469 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
470 PyMem_Free(name);
471 return rc;
472}
473
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000474#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000475static PyObject *
476win32_error(char* function, char* filename)
477{
Mark Hammond33a6da92000-08-15 00:46:38 +0000478 /* XXX We should pass the function name along in the future.
Georg Brandl38feaf02008-05-25 07:45:51 +0000479 (winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000480 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000481 Windows error object, which is non-trivial.
482 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000483 errno = GetLastError();
484 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000485 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000486 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000487 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000488}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000489
490#ifdef Py_WIN_WIDE_FILENAMES
491static PyObject *
492win32_error_unicode(char* function, Py_UNICODE* filename)
493{
494 /* XXX - see win32_error for comments on 'function' */
495 errno = GetLastError();
496 if (filename)
497 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
498 else
499 return PyErr_SetFromWindowsErr(errno);
500}
501
502static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
503{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000504}
505
Thomas Wouters477c8d52006-05-27 19:21:47 +0000506static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000507convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000508{
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000509 if (PyUnicode_CheckExact(*param))
510 Py_INCREF(*param);
511 else if (PyUnicode_Check(*param))
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000512 /* For a Unicode subtype that's not a Unicode object,
513 return a true Unicode object with the same data. */
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000514 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
515 PyUnicode_GET_SIZE(*param));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000516 else
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000517 *param = PyUnicode_FromEncodedObject(*param,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000518 Py_FileSystemDefaultEncoding,
519 "strict");
520 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000521}
522
523#endif /* Py_WIN_WIDE_FILENAMES */
524
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000525#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000526
Guido van Rossumd48f2521997-12-05 22:19:34 +0000527#if defined(PYOS_OS2)
528/**********************************************************************
529 * Helper Function to Trim and Format OS/2 Messages
530 **********************************************************************/
531 static void
532os2_formatmsg(char *msgbuf, int msglen, char *reason)
533{
534 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
535
536 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
537 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
538
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000539 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000540 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
541 }
542
543 /* Add Optional Reason Text */
544 if (reason) {
545 strcat(msgbuf, " : ");
546 strcat(msgbuf, reason);
547 }
548}
549
550/**********************************************************************
551 * Decode an OS/2 Operating System Error Code
552 *
553 * A convenience function to lookup an OS/2 error code and return a
554 * text message we can use to raise a Python exception.
555 *
556 * Notes:
557 * The messages for errors returned from the OS/2 kernel reside in
558 * the file OSO001.MSG in the \OS2 directory hierarchy.
559 *
560 **********************************************************************/
561 static char *
562os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
563{
564 APIRET rc;
565 ULONG msglen;
566
567 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
568 Py_BEGIN_ALLOW_THREADS
569 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
570 errorcode, "oso001.msg", &msglen);
571 Py_END_ALLOW_THREADS
572
573 if (rc == NO_ERROR)
574 os2_formatmsg(msgbuf, msglen, reason);
575 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000576 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000577 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000578
579 return msgbuf;
580}
581
582/* Set an OS/2-specific error and return NULL. OS/2 kernel
583 errors are not in a global variable e.g. 'errno' nor are
584 they congruent with posix error numbers. */
585
586static PyObject * os2_error(int code)
587{
588 char text[1024];
589 PyObject *v;
590
591 os2_strerror(text, sizeof(text), code, "");
592
593 v = Py_BuildValue("(is)", code, text);
594 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000595 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000596 Py_DECREF(v);
597 }
598 return NULL; /* Signal to Python that an Exception is Pending */
599}
600
601#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000602
603/* POSIX generic methods */
604
Barry Warsaw53699e91996-12-10 23:23:01 +0000605static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000606posix_fildes(PyObject *fdobj, int (*func)(int))
607{
608 int fd;
609 int res;
610 fd = PyObject_AsFileDescriptor(fdobj);
611 if (fd < 0)
612 return NULL;
613 Py_BEGIN_ALLOW_THREADS
614 res = (*func)(fd);
615 Py_END_ALLOW_THREADS
616 if (res < 0)
617 return posix_error();
618 Py_INCREF(Py_None);
619 return Py_None;
620}
Guido van Rossum21142a01999-01-08 21:05:37 +0000621
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000622#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000623static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000624unicode_file_names(void)
625{
626 static int canusewide = -1;
627 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000628 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000629 the Windows NT family. */
630 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
631 }
632 return canusewide;
633}
634#endif
Tim Peters11b23062003-04-23 02:39:17 +0000635
Guido van Rossum21142a01999-01-08 21:05:37 +0000636static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000637posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000638{
Mark Hammondef8b6542001-05-13 08:04:26 +0000639 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000640 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000641 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000642 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000643 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000644 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000645 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000646 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000647 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000648 return posix_error_with_allocated_filename(path1);
649 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000650 Py_INCREF(Py_None);
651 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000652}
653
Barry Warsaw53699e91996-12-10 23:23:01 +0000654static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000655posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000656 char *format,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000657 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000658{
Mark Hammondef8b6542001-05-13 08:04:26 +0000659 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000660 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000661 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000662 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000663 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000665 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000666 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000667 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000668 PyMem_Free(path1);
669 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000670 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000671 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000672 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000673 Py_INCREF(Py_None);
674 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000675}
676
Thomas Wouters477c8d52006-05-27 19:21:47 +0000677#ifdef Py_WIN_WIDE_FILENAMES
678static PyObject*
679win32_1str(PyObject* args, char* func,
680 char* format, BOOL (__stdcall *funcA)(LPCSTR),
681 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
682{
683 PyObject *uni;
684 char *ansi;
685 BOOL result;
686 if (unicode_file_names()) {
687 if (!PyArg_ParseTuple(args, wformat, &uni))
688 PyErr_Clear();
689 else {
690 Py_BEGIN_ALLOW_THREADS
691 result = funcW(PyUnicode_AsUnicode(uni));
692 Py_END_ALLOW_THREADS
693 if (!result)
694 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
695 Py_INCREF(Py_None);
696 return Py_None;
697 }
698 }
699 if (!PyArg_ParseTuple(args, format, &ansi))
700 return NULL;
701 Py_BEGIN_ALLOW_THREADS
702 result = funcA(ansi);
703 Py_END_ALLOW_THREADS
704 if (!result)
705 return win32_error(func, ansi);
706 Py_INCREF(Py_None);
707 return Py_None;
708
709}
710
711/* This is a reimplementation of the C library's chdir function,
712 but one that produces Win32 errors instead of DOS error codes.
713 chdir is essentially a wrapper around SetCurrentDirectory; however,
714 it also needs to set "magic" environment variables indicating
715 the per-drive current directory, which are of the form =<drive>: */
716BOOL __stdcall
717win32_chdir(LPCSTR path)
718{
719 char new_path[MAX_PATH+1];
720 int result;
721 char env[4] = "=x:";
722
723 if(!SetCurrentDirectoryA(path))
724 return FALSE;
725 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
726 if (!result)
727 return FALSE;
728 /* In the ANSI API, there should not be any paths longer
729 than MAX_PATH. */
730 assert(result <= MAX_PATH+1);
731 if (strncmp(new_path, "\\\\", 2) == 0 ||
732 strncmp(new_path, "//", 2) == 0)
733 /* UNC path, nothing to do. */
734 return TRUE;
735 env[1] = new_path[0];
736 return SetEnvironmentVariableA(env, new_path);
737}
738
739/* The Unicode version differs from the ANSI version
740 since the current directory might exceed MAX_PATH characters */
741BOOL __stdcall
742win32_wchdir(LPCWSTR path)
743{
744 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
745 int result;
746 wchar_t env[4] = L"=x:";
747
748 if(!SetCurrentDirectoryW(path))
749 return FALSE;
750 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
751 if (!result)
752 return FALSE;
753 if (result > MAX_PATH+1) {
754 new_path = malloc(result);
755 if (!new_path) {
756 SetLastError(ERROR_OUTOFMEMORY);
757 return FALSE;
758 }
759 }
760 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
761 wcsncmp(new_path, L"//", 2) == 0)
762 /* UNC path, nothing to do. */
763 return TRUE;
764 env[1] = new_path[0];
765 result = SetEnvironmentVariableW(env, new_path);
766 if (new_path != _new_path)
767 free(new_path);
768 return result;
769}
770#endif
771
Martin v. Löwis14694662006-02-03 12:54:16 +0000772#ifdef MS_WINDOWS
773/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
774 - time stamps are restricted to second resolution
775 - file modification times suffer from forth-and-back conversions between
776 UTC and local time
777 Therefore, we implement our own stat, based on the Win32 API directly.
778*/
779#define HAVE_STAT_NSEC 1
780
781struct win32_stat{
782 int st_dev;
783 __int64 st_ino;
784 unsigned short st_mode;
785 int st_nlink;
786 int st_uid;
787 int st_gid;
788 int st_rdev;
789 __int64 st_size;
790 int st_atime;
791 int st_atime_nsec;
792 int st_mtime;
793 int st_mtime_nsec;
794 int st_ctime;
795 int st_ctime_nsec;
796};
797
798static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
799
800static void
801FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
802{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000803 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
804 /* Cannot simply cast and dereference in_ptr,
805 since it might not be aligned properly */
806 __int64 in;
807 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000808 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
809 /* XXX Win32 supports time stamps past 2038; we currently don't */
810 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
811}
812
Thomas Wouters477c8d52006-05-27 19:21:47 +0000813static void
814time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
815{
816 /* XXX endianness */
817 __int64 out;
818 out = time_in + secs_between_epochs;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000819 out = out * 10000000 + nsec_in / 100;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000820 memcpy(out_ptr, &out, sizeof(out));
821}
822
Martin v. Löwis14694662006-02-03 12:54:16 +0000823/* Below, we *know* that ugo+r is 0444 */
824#if _S_IREAD != 0400
825#error Unsupported C library
826#endif
827static int
828attributes_to_mode(DWORD attr)
829{
830 int m = 0;
831 if (attr & FILE_ATTRIBUTE_DIRECTORY)
832 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
833 else
834 m |= _S_IFREG;
835 if (attr & FILE_ATTRIBUTE_READONLY)
836 m |= 0444;
837 else
838 m |= 0666;
839 return m;
840}
841
842static int
843attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
844{
845 memset(result, 0, sizeof(*result));
846 result->st_mode = attributes_to_mode(info->dwFileAttributes);
847 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
848 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
849 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
850 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
851
852 return 0;
853}
854
Thomas Wouters89f507f2006-12-13 04:49:30 +0000855/* Emulate GetFileAttributesEx[AW] on Windows 95 */
856static int checked = 0;
857static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
858static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
859static void
860check_gfax()
861{
862 HINSTANCE hKernel32;
863 if (checked)
864 return;
865 checked = 1;
866 hKernel32 = GetModuleHandle("KERNEL32");
867 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
868 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
869}
870
Guido van Rossumd8faa362007-04-27 19:54:29 +0000871static BOOL
872attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
873{
874 HANDLE hFindFile;
875 WIN32_FIND_DATAA FileData;
876 hFindFile = FindFirstFileA(pszFile, &FileData);
877 if (hFindFile == INVALID_HANDLE_VALUE)
878 return FALSE;
879 FindClose(hFindFile);
880 pfad->dwFileAttributes = FileData.dwFileAttributes;
881 pfad->ftCreationTime = FileData.ftCreationTime;
882 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
883 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
884 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
885 pfad->nFileSizeLow = FileData.nFileSizeLow;
886 return TRUE;
887}
888
889static BOOL
890attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
891{
892 HANDLE hFindFile;
893 WIN32_FIND_DATAW FileData;
894 hFindFile = FindFirstFileW(pszFile, &FileData);
895 if (hFindFile == INVALID_HANDLE_VALUE)
896 return FALSE;
897 FindClose(hFindFile);
898 pfad->dwFileAttributes = FileData.dwFileAttributes;
899 pfad->ftCreationTime = FileData.ftCreationTime;
900 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
901 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
902 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
903 pfad->nFileSizeLow = FileData.nFileSizeLow;
904 return TRUE;
905}
906
Thomas Wouters89f507f2006-12-13 04:49:30 +0000907static BOOL WINAPI
908Py_GetFileAttributesExA(LPCSTR pszFile,
909 GET_FILEEX_INFO_LEVELS level,
910 LPVOID pv)
911{
912 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000913 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
914 /* First try to use the system's implementation, if that is
915 available and either succeeds to gives an error other than
916 that it isn't implemented. */
917 check_gfax();
918 if (gfaxa) {
919 result = gfaxa(pszFile, level, pv);
920 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
921 return result;
922 }
923 /* It's either not present, or not implemented.
924 Emulate using FindFirstFile. */
925 if (level != GetFileExInfoStandard) {
926 SetLastError(ERROR_INVALID_PARAMETER);
927 return FALSE;
928 }
929 /* Use GetFileAttributes to validate that the file name
930 does not contain wildcards (which FindFirstFile would
931 accept). */
932 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
933 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000934 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000935}
936
937static BOOL WINAPI
938Py_GetFileAttributesExW(LPCWSTR pszFile,
939 GET_FILEEX_INFO_LEVELS level,
940 LPVOID pv)
941{
942 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000943 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
944 /* First try to use the system's implementation, if that is
945 available and either succeeds to gives an error other than
946 that it isn't implemented. */
947 check_gfax();
948 if (gfaxa) {
949 result = gfaxw(pszFile, level, pv);
950 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
951 return result;
952 }
953 /* It's either not present, or not implemented.
954 Emulate using FindFirstFile. */
955 if (level != GetFileExInfoStandard) {
956 SetLastError(ERROR_INVALID_PARAMETER);
957 return FALSE;
958 }
959 /* Use GetFileAttributes to validate that the file name
960 does not contain wildcards (which FindFirstFile would
961 accept). */
962 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
963 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000964 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000965}
966
Martin v. Löwis14694662006-02-03 12:54:16 +0000967static int
968win32_stat(const char* path, struct win32_stat *result)
969{
970 WIN32_FILE_ATTRIBUTE_DATA info;
971 int code;
972 char *dot;
973 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +0000974 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +0000975 if (GetLastError() != ERROR_SHARING_VIOLATION) {
976 /* Protocol violation: we explicitly clear errno, instead of
977 setting it to a POSIX error. Callers should use GetLastError. */
978 errno = 0;
979 return -1;
980 } else {
981 /* Could not get attributes on open file. Fall back to
982 reading the directory. */
983 if (!attributes_from_dir(path, &info)) {
984 /* Very strange. This should not fail now */
985 errno = 0;
986 return -1;
987 }
988 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000989 }
990 code = attribute_data_to_stat(&info, result);
991 if (code != 0)
992 return code;
993 /* Set S_IFEXEC if it is an .exe, .bat, ... */
994 dot = strrchr(path, '.');
995 if (dot) {
996 if (stricmp(dot, ".bat") == 0 ||
997 stricmp(dot, ".cmd") == 0 ||
998 stricmp(dot, ".exe") == 0 ||
999 stricmp(dot, ".com") == 0)
1000 result->st_mode |= 0111;
1001 }
1002 return code;
1003}
1004
1005static int
1006win32_wstat(const wchar_t* path, struct win32_stat *result)
1007{
1008 int code;
1009 const wchar_t *dot;
1010 WIN32_FILE_ATTRIBUTE_DATA info;
1011 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001012 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001013 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1014 /* Protocol violation: we explicitly clear errno, instead of
1015 setting it to a POSIX error. Callers should use GetLastError. */
1016 errno = 0;
1017 return -1;
1018 } else {
1019 /* Could not get attributes on open file. Fall back to
1020 reading the directory. */
1021 if (!attributes_from_dir_w(path, &info)) {
1022 /* Very strange. This should not fail now */
1023 errno = 0;
1024 return -1;
1025 }
1026 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001027 }
1028 code = attribute_data_to_stat(&info, result);
1029 if (code < 0)
1030 return code;
1031 /* Set IFEXEC if it is an .exe, .bat, ... */
1032 dot = wcsrchr(path, '.');
1033 if (dot) {
1034 if (_wcsicmp(dot, L".bat") == 0 ||
1035 _wcsicmp(dot, L".cmd") == 0 ||
1036 _wcsicmp(dot, L".exe") == 0 ||
1037 _wcsicmp(dot, L".com") == 0)
1038 result->st_mode |= 0111;
1039 }
1040 return code;
1041}
1042
1043static int
1044win32_fstat(int file_number, struct win32_stat *result)
1045{
1046 BY_HANDLE_FILE_INFORMATION info;
1047 HANDLE h;
1048 int type;
1049
1050 h = (HANDLE)_get_osfhandle(file_number);
1051
1052 /* Protocol violation: we explicitly clear errno, instead of
1053 setting it to a POSIX error. Callers should use GetLastError. */
1054 errno = 0;
1055
1056 if (h == INVALID_HANDLE_VALUE) {
1057 /* This is really a C library error (invalid file handle).
1058 We set the Win32 error to the closes one matching. */
1059 SetLastError(ERROR_INVALID_HANDLE);
1060 return -1;
1061 }
1062 memset(result, 0, sizeof(*result));
1063
1064 type = GetFileType(h);
1065 if (type == FILE_TYPE_UNKNOWN) {
1066 DWORD error = GetLastError();
1067 if (error != 0) {
1068 return -1;
1069 }
1070 /* else: valid but unknown file */
1071 }
1072
1073 if (type != FILE_TYPE_DISK) {
1074 if (type == FILE_TYPE_CHAR)
1075 result->st_mode = _S_IFCHR;
1076 else if (type == FILE_TYPE_PIPE)
1077 result->st_mode = _S_IFIFO;
1078 return 0;
1079 }
1080
1081 if (!GetFileInformationByHandle(h, &info)) {
1082 return -1;
1083 }
1084
1085 /* similar to stat() */
1086 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1087 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1088 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1089 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1090 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1091 /* specific to fstat() */
1092 result->st_nlink = info.nNumberOfLinks;
1093 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1094 return 0;
1095}
1096
1097#endif /* MS_WINDOWS */
1098
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001099PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001100"stat_result: Result from stat or lstat.\n\n\
1101This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001102 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001103or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1104\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001105Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1106or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001107\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001108See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001109
1110static PyStructSequence_Field stat_result_fields[] = {
1111 {"st_mode", "protection bits"},
1112 {"st_ino", "inode"},
1113 {"st_dev", "device"},
1114 {"st_nlink", "number of hard links"},
1115 {"st_uid", "user ID of owner"},
1116 {"st_gid", "group ID of owner"},
1117 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001118 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1119 {NULL, "integer time of last access"},
1120 {NULL, "integer time of last modification"},
1121 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001122 {"st_atime", "time of last access"},
1123 {"st_mtime", "time of last modification"},
1124 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001125#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001126 {"st_blksize", "blocksize for filesystem I/O"},
1127#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001128#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001129 {"st_blocks", "number of blocks allocated"},
1130#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001131#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001132 {"st_rdev", "device type (if inode device)"},
1133#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001134#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1135 {"st_flags", "user defined flags for file"},
1136#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001137#ifdef HAVE_STRUCT_STAT_ST_GEN
1138 {"st_gen", "generation number"},
1139#endif
1140#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1141 {"st_birthtime", "time of creation"},
1142#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001143 {0}
1144};
1145
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001146#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001147#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001148#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001149#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001150#endif
1151
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001152#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001153#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1154#else
1155#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1156#endif
1157
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001158#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001159#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1160#else
1161#define ST_RDEV_IDX ST_BLOCKS_IDX
1162#endif
1163
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001164#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1165#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1166#else
1167#define ST_FLAGS_IDX ST_RDEV_IDX
1168#endif
1169
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001170#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001171#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001172#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001173#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001174#endif
1175
1176#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1177#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1178#else
1179#define ST_BIRTHTIME_IDX ST_GEN_IDX
1180#endif
1181
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001182static PyStructSequence_Desc stat_result_desc = {
1183 "stat_result", /* name */
1184 stat_result__doc__, /* doc */
1185 stat_result_fields,
1186 10
1187};
1188
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001189PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001190"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1191This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001192 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001193or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001194\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001195See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001196
1197static PyStructSequence_Field statvfs_result_fields[] = {
1198 {"f_bsize", },
1199 {"f_frsize", },
1200 {"f_blocks", },
1201 {"f_bfree", },
1202 {"f_bavail", },
1203 {"f_files", },
1204 {"f_ffree", },
1205 {"f_favail", },
1206 {"f_flag", },
1207 {"f_namemax",},
1208 {0}
1209};
1210
1211static PyStructSequence_Desc statvfs_result_desc = {
1212 "statvfs_result", /* name */
1213 statvfs_result__doc__, /* doc */
1214 statvfs_result_fields,
1215 10
1216};
1217
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001218static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001219static PyTypeObject StatResultType;
1220static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001221static newfunc structseq_new;
1222
1223static PyObject *
1224statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1225{
1226 PyStructSequence *result;
1227 int i;
1228
1229 result = (PyStructSequence*)structseq_new(type, args, kwds);
1230 if (!result)
1231 return NULL;
1232 /* If we have been initialized from a tuple,
1233 st_?time might be set to None. Initialize it
1234 from the int slots. */
1235 for (i = 7; i <= 9; i++) {
1236 if (result->ob_item[i+3] == Py_None) {
1237 Py_DECREF(Py_None);
1238 Py_INCREF(result->ob_item[i]);
1239 result->ob_item[i+3] = result->ob_item[i];
1240 }
1241 }
1242 return (PyObject*)result;
1243}
1244
1245
1246
1247/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001248static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001249
1250PyDoc_STRVAR(stat_float_times__doc__,
1251"stat_float_times([newval]) -> oldval\n\n\
1252Determine whether os.[lf]stat represents time stamps as float objects.\n\
1253If newval is True, future calls to stat() return floats, if it is False,\n\
1254future calls return ints. \n\
1255If newval is omitted, return the current setting.\n");
1256
1257static PyObject*
1258stat_float_times(PyObject* self, PyObject *args)
1259{
1260 int newval = -1;
1261 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1262 return NULL;
1263 if (newval == -1)
1264 /* Return old value */
1265 return PyBool_FromLong(_stat_float_times);
1266 _stat_float_times = newval;
1267 Py_INCREF(Py_None);
1268 return Py_None;
1269}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001270
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001271static void
1272fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1273{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001274 PyObject *fval,*ival;
1275#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001276 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001277#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001278 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001279#endif
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001280 if (!ival)
1281 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001282 if (_stat_float_times) {
1283 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1284 } else {
1285 fval = ival;
1286 Py_INCREF(fval);
1287 }
1288 PyStructSequence_SET_ITEM(v, index, ival);
1289 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001290}
1291
Tim Peters5aa91602002-01-30 05:46:57 +00001292/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001293 (used by posix_stat() and posix_fstat()) */
1294static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001295_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001296{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001297 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001298 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001299 if (v == NULL)
1300 return NULL;
1301
Christian Heimes217cfd12007-12-02 14:31:20 +00001302 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001303#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001304 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001305 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001306#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001307 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001308#endif
1309#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001310 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001311 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001312#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001313 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001314#endif
Christian Heimes217cfd12007-12-02 14:31:20 +00001315 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1316 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1317 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001318#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001319 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001320 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001321#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001322 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001323#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001324
Martin v. Löwis14694662006-02-03 12:54:16 +00001325#if defined(HAVE_STAT_TV_NSEC)
1326 ansec = st->st_atim.tv_nsec;
1327 mnsec = st->st_mtim.tv_nsec;
1328 cnsec = st->st_ctim.tv_nsec;
1329#elif defined(HAVE_STAT_TV_NSEC2)
1330 ansec = st->st_atimespec.tv_nsec;
1331 mnsec = st->st_mtimespec.tv_nsec;
1332 cnsec = st->st_ctimespec.tv_nsec;
1333#elif defined(HAVE_STAT_NSEC)
1334 ansec = st->st_atime_nsec;
1335 mnsec = st->st_mtime_nsec;
1336 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001337#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001338 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001339#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001340 fill_time(v, 7, st->st_atime, ansec);
1341 fill_time(v, 8, st->st_mtime, mnsec);
1342 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001343
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001344#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001345 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001346 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001347#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001348#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001349 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001350 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001351#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001352#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001353 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001354 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001355#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001356#ifdef HAVE_STRUCT_STAT_ST_GEN
1357 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001358 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001359#endif
1360#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1361 {
1362 PyObject *val;
1363 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001364 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001365#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001366 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001367#else
1368 bnsec = 0;
1369#endif
1370 if (_stat_float_times) {
1371 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1372 } else {
Christian Heimes217cfd12007-12-02 14:31:20 +00001373 val = PyLong_FromLong((long)bsec);
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001374 }
1375 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1376 val);
1377 }
1378#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001379#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1380 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001381 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001382#endif
Fred Drake699f3522000-06-29 21:12:41 +00001383
1384 if (PyErr_Occurred()) {
1385 Py_DECREF(v);
1386 return NULL;
1387 }
1388
1389 return v;
1390}
1391
Martin v. Löwisd8948722004-06-02 09:57:56 +00001392#ifdef MS_WINDOWS
1393
1394/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1395 where / can be used in place of \ and the trailing slash is optional.
1396 Both SERVER and SHARE must have at least one character.
1397*/
1398
1399#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1400#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001401#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001402#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001403#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001404
Tim Peters4ad82172004-08-30 17:02:04 +00001405static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001406IsUNCRootA(char *path, int pathlen)
1407{
1408 #define ISSLASH ISSLASHA
1409
1410 int i, share;
1411
1412 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1413 /* minimum UNCRoot is \\x\y */
1414 return FALSE;
1415 for (i = 2; i < pathlen ; i++)
1416 if (ISSLASH(path[i])) break;
1417 if (i == 2 || i == pathlen)
1418 /* do not allow \\\SHARE or \\SERVER */
1419 return FALSE;
1420 share = i+1;
1421 for (i = share; i < pathlen; i++)
1422 if (ISSLASH(path[i])) break;
1423 return (i != share && (i == pathlen || i == pathlen-1));
1424
1425 #undef ISSLASH
1426}
1427
1428#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001429static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001430IsUNCRootW(Py_UNICODE *path, int pathlen)
1431{
1432 #define ISSLASH ISSLASHW
1433
1434 int i, share;
1435
1436 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1437 /* minimum UNCRoot is \\x\y */
1438 return FALSE;
1439 for (i = 2; i < pathlen ; i++)
1440 if (ISSLASH(path[i])) break;
1441 if (i == 2 || i == pathlen)
1442 /* do not allow \\\SHARE or \\SERVER */
1443 return FALSE;
1444 share = i+1;
1445 for (i = share; i < pathlen; i++)
1446 if (ISSLASH(path[i])) break;
1447 return (i != share && (i == pathlen || i == pathlen-1));
1448
1449 #undef ISSLASH
1450}
1451#endif /* Py_WIN_WIDE_FILENAMES */
1452#endif /* MS_WINDOWS */
1453
Barry Warsaw53699e91996-12-10 23:23:01 +00001454static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001455posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001456 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001457#ifdef __VMS
1458 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1459#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001460 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001461#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001462 char *wformat,
1463 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001464{
Fred Drake699f3522000-06-29 21:12:41 +00001465 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001466 char *path = NULL; /* pass this to stat; do not free() it */
1467 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001468 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001469 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001470
1471#ifdef Py_WIN_WIDE_FILENAMES
1472 /* If on wide-character-capable OS see if argument
1473 is Unicode and if so use wide API. */
1474 if (unicode_file_names()) {
1475 PyUnicodeObject *po;
1476 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001477 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1478
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001479 Py_BEGIN_ALLOW_THREADS
1480 /* PyUnicode_AS_UNICODE result OK without
1481 thread lock as it is a simple dereference. */
1482 res = wstatfunc(wpath, &st);
1483 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001484
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001485 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001486 return win32_error_unicode("stat", wpath);
1487 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001488 }
1489 /* Drop the argument parsing error as narrow strings
1490 are also valid. */
1491 PyErr_Clear();
1492 }
1493#endif
1494
Tim Peters5aa91602002-01-30 05:46:57 +00001495 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001496 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001497 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001498 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001499
Barry Warsaw53699e91996-12-10 23:23:01 +00001500 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001501 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001502 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001503
1504 if (res != 0) {
1505#ifdef MS_WINDOWS
1506 result = win32_error("stat", pathfree);
1507#else
1508 result = posix_error_with_filename(pathfree);
1509#endif
1510 }
1511 else
1512 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001513
Tim Peters500bd032001-12-19 19:05:01 +00001514 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001515 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001516}
1517
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001518/* POSIX methods */
1519
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001520PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001521"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001522Use the real uid/gid to test for access to a path. Note that most\n\
1523operations will use the effective uid/gid, therefore this routine can\n\
1524be used in a suid/sgid environment to test if the invoking user has the\n\
1525specified access to the path. The mode argument can be F_OK to test\n\
1526existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001527
1528static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001529posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001530{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001531 char *path;
1532 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001533
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001534#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001536 if (unicode_file_names()) {
1537 PyUnicodeObject *po;
1538 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1539 Py_BEGIN_ALLOW_THREADS
1540 /* PyUnicode_AS_UNICODE OK without thread lock as
1541 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001542 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001543 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001544 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001545 }
1546 /* Drop the argument parsing error as narrow strings
1547 are also valid. */
1548 PyErr_Clear();
1549 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001550 if (!PyArg_ParseTuple(args, "eti:access",
1551 Py_FileSystemDefaultEncoding, &path, &mode))
1552 return 0;
1553 Py_BEGIN_ALLOW_THREADS
1554 attr = GetFileAttributesA(path);
1555 Py_END_ALLOW_THREADS
1556 PyMem_Free(path);
1557finish:
1558 if (attr == 0xFFFFFFFF)
1559 /* File does not exist, or cannot read attributes */
1560 return PyBool_FromLong(0);
1561 /* Access is possible if either write access wasn't requested, or
Guido van Rossumb00324f2007-12-04 01:13:14 +00001562 the file isn't read-only, or if it's a directory, as there are
1563 no read-only directories on Windows. */
1564 return PyBool_FromLong(!(mode & 2)
1565 || !(attr & FILE_ATTRIBUTE_READONLY)
1566 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001567#else
1568 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001569 if (!PyArg_ParseTuple(args, "eti:access",
1570 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001571 return NULL;
1572 Py_BEGIN_ALLOW_THREADS
1573 res = access(path, mode);
1574 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001575 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001576 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001577#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001578}
1579
Guido van Rossumd371ff11999-01-25 16:12:23 +00001580#ifndef F_OK
1581#define F_OK 0
1582#endif
1583#ifndef R_OK
1584#define R_OK 4
1585#endif
1586#ifndef W_OK
1587#define W_OK 2
1588#endif
1589#ifndef X_OK
1590#define X_OK 1
1591#endif
1592
1593#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001594PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001595"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001596Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001597
1598static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001599posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001600{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001601 int id;
1602 char *ret;
1603
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001604 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001605 return NULL;
1606
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001607#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001608 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001609 if (id == 0) {
1610 ret = ttyname();
1611 }
1612 else {
1613 ret = NULL;
1614 }
1615#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001616 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001617#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001618 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001619 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001620 return PyUnicode_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001621}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001622#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001623
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001624#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001625PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001626"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001627Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001628
1629static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001630posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001631{
1632 char *ret;
1633 char buffer[L_ctermid];
1634
Greg Wardb48bc172000-03-01 21:51:56 +00001635#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001636 ret = ctermid_r(buffer);
1637#else
1638 ret = ctermid(buffer);
1639#endif
1640 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001641 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001642 return PyUnicode_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001643}
1644#endif
1645
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001646PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001647"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001648Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001649
Barry Warsaw53699e91996-12-10 23:23:01 +00001650static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001651posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001652{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001653#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001654 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001655#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001656 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001657#elif defined(__VMS)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001658 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001659#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001660 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001661#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001662}
1663
Fred Drake4d1e64b2002-04-15 19:40:07 +00001664#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001665PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001666"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001667Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001668opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001669
1670static PyObject *
1671posix_fchdir(PyObject *self, PyObject *fdobj)
1672{
1673 return posix_fildes(fdobj, fchdir);
1674}
1675#endif /* HAVE_FCHDIR */
1676
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001677
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001678PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001679"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001680Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001681
Barry Warsaw53699e91996-12-10 23:23:01 +00001682static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001683posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001684{
Mark Hammondef8b6542001-05-13 08:04:26 +00001685 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001686 int i;
1687 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001688#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001689 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001690 if (unicode_file_names()) {
1691 PyUnicodeObject *po;
1692 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1693 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001694 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1695 if (attr != 0xFFFFFFFF) {
1696 if (i & _S_IWRITE)
1697 attr &= ~FILE_ATTRIBUTE_READONLY;
1698 else
1699 attr |= FILE_ATTRIBUTE_READONLY;
1700 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1701 }
1702 else
1703 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001704 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001705 if (!res)
1706 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001707 PyUnicode_AS_UNICODE(po));
1708 Py_INCREF(Py_None);
1709 return Py_None;
1710 }
1711 /* Drop the argument parsing error as narrow strings
1712 are also valid. */
1713 PyErr_Clear();
1714 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001715 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1716 &path, &i))
1717 return NULL;
1718 Py_BEGIN_ALLOW_THREADS
1719 attr = GetFileAttributesA(path);
1720 if (attr != 0xFFFFFFFF) {
1721 if (i & _S_IWRITE)
1722 attr &= ~FILE_ATTRIBUTE_READONLY;
1723 else
1724 attr |= FILE_ATTRIBUTE_READONLY;
1725 res = SetFileAttributesA(path, attr);
1726 }
1727 else
1728 res = 0;
1729 Py_END_ALLOW_THREADS
1730 if (!res) {
1731 win32_error("chmod", path);
1732 PyMem_Free(path);
1733 return NULL;
1734 }
1735 PyMem_Free(path);
1736 Py_INCREF(Py_None);
1737 return Py_None;
1738#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001739 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001740 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001741 return NULL;
1742 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001743 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001744 Py_END_ALLOW_THREADS
1745 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001746 return posix_error_with_allocated_filename(path);
1747 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001748 Py_INCREF(Py_None);
1749 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001750#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001751}
1752
Christian Heimes4e30a842007-11-30 22:12:06 +00001753#ifdef HAVE_FCHMOD
1754PyDoc_STRVAR(posix_fchmod__doc__,
1755"fchmod(fd, mode)\n\n\
1756Change the access permissions of the file given by file\n\
1757descriptor fd.");
1758
1759static PyObject *
1760posix_fchmod(PyObject *self, PyObject *args)
1761{
1762 int fd, mode, res;
1763 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1764 return NULL;
1765 Py_BEGIN_ALLOW_THREADS
1766 res = fchmod(fd, mode);
1767 Py_END_ALLOW_THREADS
1768 if (res < 0)
1769 return posix_error();
1770 Py_RETURN_NONE;
1771}
1772#endif /* HAVE_FCHMOD */
1773
1774#ifdef HAVE_LCHMOD
1775PyDoc_STRVAR(posix_lchmod__doc__,
1776"lchmod(path, mode)\n\n\
1777Change the access permissions of a file. If path is a symlink, this\n\
1778affects the link itself rather than the target.");
1779
1780static PyObject *
1781posix_lchmod(PyObject *self, PyObject *args)
1782{
1783 char *path = NULL;
1784 int i;
1785 int res;
1786 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1787 &path, &i))
1788 return NULL;
1789 Py_BEGIN_ALLOW_THREADS
1790 res = lchmod(path, i);
1791 Py_END_ALLOW_THREADS
1792 if (res < 0)
1793 return posix_error_with_allocated_filename(path);
1794 PyMem_Free(path);
1795 Py_RETURN_NONE;
1796}
1797#endif /* HAVE_LCHMOD */
1798
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001799
Thomas Wouterscf297e42007-02-23 15:07:44 +00001800#ifdef HAVE_CHFLAGS
1801PyDoc_STRVAR(posix_chflags__doc__,
1802"chflags(path, flags)\n\n\
1803Set file flags.");
1804
1805static PyObject *
1806posix_chflags(PyObject *self, PyObject *args)
1807{
1808 char *path;
1809 unsigned long flags;
1810 int res;
1811 if (!PyArg_ParseTuple(args, "etk:chflags",
1812 Py_FileSystemDefaultEncoding, &path, &flags))
1813 return NULL;
1814 Py_BEGIN_ALLOW_THREADS
1815 res = chflags(path, flags);
1816 Py_END_ALLOW_THREADS
1817 if (res < 0)
1818 return posix_error_with_allocated_filename(path);
1819 PyMem_Free(path);
1820 Py_INCREF(Py_None);
1821 return Py_None;
1822}
1823#endif /* HAVE_CHFLAGS */
1824
1825#ifdef HAVE_LCHFLAGS
1826PyDoc_STRVAR(posix_lchflags__doc__,
1827"lchflags(path, flags)\n\n\
1828Set file flags.\n\
1829This function will not follow symbolic links.");
1830
1831static PyObject *
1832posix_lchflags(PyObject *self, PyObject *args)
1833{
1834 char *path;
1835 unsigned long flags;
1836 int res;
1837 if (!PyArg_ParseTuple(args, "etk:lchflags",
1838 Py_FileSystemDefaultEncoding, &path, &flags))
1839 return NULL;
1840 Py_BEGIN_ALLOW_THREADS
1841 res = lchflags(path, flags);
1842 Py_END_ALLOW_THREADS
1843 if (res < 0)
1844 return posix_error_with_allocated_filename(path);
1845 PyMem_Free(path);
1846 Py_INCREF(Py_None);
1847 return Py_None;
1848}
1849#endif /* HAVE_LCHFLAGS */
1850
Martin v. Löwis244edc82001-10-04 22:44:26 +00001851#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001852PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001853"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001854Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001855
1856static PyObject *
1857posix_chroot(PyObject *self, PyObject *args)
1858{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001859 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001860}
1861#endif
1862
Guido van Rossum21142a01999-01-08 21:05:37 +00001863#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001864PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001865"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001866force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001867
1868static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001869posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001870{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001871 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001872}
1873#endif /* HAVE_FSYNC */
1874
1875#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001876
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001877#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001878extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1879#endif
1880
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001881PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001882"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001883force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001884 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001885
1886static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001887posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001888{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001889 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001890}
1891#endif /* HAVE_FDATASYNC */
1892
1893
Fredrik Lundh10723342000-07-10 16:38:09 +00001894#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001895PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001896"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001897Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001898
Barry Warsaw53699e91996-12-10 23:23:01 +00001899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001900posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001901{
Mark Hammondef8b6542001-05-13 08:04:26 +00001902 char *path = NULL;
Christian Heimesd5e2b6f2008-03-19 21:50:51 +00001903 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001904 int res;
Christian Heimesd5e2b6f2008-03-19 21:50:51 +00001905 if (!PyArg_ParseTuple(args, "etll:chown",
Tim Peters5aa91602002-01-30 05:46:57 +00001906 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001907 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001908 return NULL;
1909 Py_BEGIN_ALLOW_THREADS
1910 res = chown(path, (uid_t) uid, (gid_t) gid);
1911 Py_END_ALLOW_THREADS
1912 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001913 return posix_error_with_allocated_filename(path);
1914 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001915 Py_INCREF(Py_None);
1916 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001917}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001918#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001919
Christian Heimes4e30a842007-11-30 22:12:06 +00001920#ifdef HAVE_FCHOWN
1921PyDoc_STRVAR(posix_fchown__doc__,
1922"fchown(fd, uid, gid)\n\n\
1923Change the owner and group id of the file given by file descriptor\n\
1924fd to the numeric uid and gid.");
1925
1926static PyObject *
1927posix_fchown(PyObject *self, PyObject *args)
1928{
1929 int fd, uid, gid;
1930 int res;
1931 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
1932 return NULL;
1933 Py_BEGIN_ALLOW_THREADS
1934 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1935 Py_END_ALLOW_THREADS
1936 if (res < 0)
1937 return posix_error();
1938 Py_RETURN_NONE;
1939}
1940#endif /* HAVE_FCHOWN */
1941
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001942#ifdef HAVE_LCHOWN
1943PyDoc_STRVAR(posix_lchown__doc__,
1944"lchown(path, uid, gid)\n\n\
1945Change the owner and group id of path to the numeric uid and gid.\n\
1946This function will not follow symbolic links.");
1947
1948static PyObject *
1949posix_lchown(PyObject *self, PyObject *args)
1950{
1951 char *path = NULL;
1952 int uid, gid;
1953 int res;
1954 if (!PyArg_ParseTuple(args, "etii:lchown",
1955 Py_FileSystemDefaultEncoding, &path,
1956 &uid, &gid))
1957 return NULL;
1958 Py_BEGIN_ALLOW_THREADS
1959 res = lchown(path, (uid_t) uid, (gid_t) gid);
1960 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001961 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001962 return posix_error_with_allocated_filename(path);
1963 PyMem_Free(path);
1964 Py_INCREF(Py_None);
1965 return Py_None;
1966}
1967#endif /* HAVE_LCHOWN */
1968
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001969
Guido van Rossum36bc6801995-06-14 22:54:23 +00001970#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00001971static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00001972posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001973{
1974 char buf[1026];
1975 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001976
1977#ifdef Py_WIN_WIDE_FILENAMES
Guido van Rossumf0af3e32008-10-02 18:55:37 +00001978 if (!use_bytes && unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001979 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001980 wchar_t *wbuf2 = wbuf;
1981 PyObject *resobj;
Guido van Rossumf0af3e32008-10-02 18:55:37 +00001982 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001983 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001984 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
1985 /* If the buffer is large enough, len does not include the
1986 terminating \0. If the buffer is too small, len includes
1987 the space needed for the terminator. */
1988 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
1989 wbuf2 = malloc(len * sizeof(wchar_t));
1990 if (wbuf2)
1991 len = GetCurrentDirectoryW(len, wbuf2);
1992 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001993 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001994 if (!wbuf2) {
1995 PyErr_NoMemory();
1996 return NULL;
1997 }
1998 if (!len) {
1999 if (wbuf2 != wbuf) free(wbuf2);
2000 return win32_error("getcwdu", NULL);
2001 }
2002 resobj = PyUnicode_FromWideChar(wbuf2, len);
2003 if (wbuf2 != wbuf) free(wbuf2);
2004 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002005 }
2006#endif
2007
2008 Py_BEGIN_ALLOW_THREADS
2009#if defined(PYOS_OS2) && defined(PYCC_GCC)
2010 res = _getcwd2(buf, sizeof buf);
2011#else
2012 res = getcwd(buf, sizeof buf);
2013#endif
2014 Py_END_ALLOW_THREADS
2015 if (res == NULL)
2016 return posix_error();
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002017 if (use_bytes)
2018 return PyBytes_FromStringAndSize(buf, strlen(buf));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002019 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2020}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002021
2022PyDoc_STRVAR(posix_getcwd__doc__,
2023"getcwd() -> path\n\n\
2024Return a unicode string representing the current working directory.");
2025
2026static PyObject *
2027posix_getcwd_unicode(PyObject *self)
2028{
2029 return posix_getcwd(0);
2030}
2031
2032PyDoc_STRVAR(posix_getcwdb__doc__,
2033"getcwdb() -> path\n\n\
2034Return a bytes string representing the current working directory.");
2035
2036static PyObject *
2037posix_getcwd_bytes(PyObject *self)
2038{
2039 return posix_getcwd(1);
2040}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002041#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002042
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002043
Guido van Rossumb6775db1994-08-01 11:34:53 +00002044#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002045PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002046"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002047Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002048
Barry Warsaw53699e91996-12-10 23:23:01 +00002049static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002050posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002051{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002052 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002053}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002054#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002055
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002056
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002057PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002058"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002059Return a list containing the names of the entries in the directory.\n\
2060\n\
2061 path: path of directory to list\n\
2062\n\
2063The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002064entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002065
Barry Warsaw53699e91996-12-10 23:23:01 +00002066static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002067posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002068{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002069 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002070 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002071#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002072
Barry Warsaw53699e91996-12-10 23:23:01 +00002073 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002074 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002075 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002076 WIN32_FIND_DATA FileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002077 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002078 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002079 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002080
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002081#ifdef Py_WIN_WIDE_FILENAMES
2082 /* If on wide-character-capable OS see if argument
2083 is Unicode and if so use wide API. */
2084 if (unicode_file_names()) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002085 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002086 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2087 WIN32_FIND_DATAW wFileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002088 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002089 Py_UNICODE wch;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002090 /* Overallocate for \\*.*\0 */
2091 len = PyUnicode_GET_SIZE(po);
2092 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2093 if (!wnamebuf) {
2094 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002095 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002096 }
2097 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2098 wch = len > 0 ? wnamebuf[len-1] : '\0';
2099 if (wch != L'/' && wch != L'\\' && wch != L':')
2100 wnamebuf[len++] = L'\\';
2101 wcscpy(wnamebuf + len, L"*.*");
2102 if ((d = PyList_New(0)) == NULL) {
2103 free(wnamebuf);
2104 return NULL;
2105 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002106 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2107 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002108 int error = GetLastError();
2109 if (error == ERROR_FILE_NOT_FOUND) {
2110 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002111 return d;
2112 }
2113 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002114 win32_error_unicode("FindFirstFileW", wnamebuf);
2115 free(wnamebuf);
2116 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002117 }
2118 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002119 /* Skip over . and .. */
2120 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2121 wcscmp(wFileData.cFileName, L"..") != 0) {
2122 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2123 if (v == NULL) {
2124 Py_DECREF(d);
2125 d = NULL;
2126 break;
2127 }
2128 if (PyList_Append(d, v) != 0) {
2129 Py_DECREF(v);
2130 Py_DECREF(d);
2131 d = NULL;
2132 break;
2133 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002134 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002135 }
Georg Brandl622927b2006-03-07 12:48:03 +00002136 Py_BEGIN_ALLOW_THREADS
2137 result = FindNextFileW(hFindFile, &wFileData);
2138 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002139 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2140 it got to the end of the directory. */
2141 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2142 Py_DECREF(d);
2143 win32_error_unicode("FindNextFileW", wnamebuf);
2144 FindClose(hFindFile);
2145 free(wnamebuf);
2146 return NULL;
2147 }
Georg Brandl622927b2006-03-07 12:48:03 +00002148 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002149
2150 if (FindClose(hFindFile) == FALSE) {
2151 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002152 win32_error_unicode("FindClose", wnamebuf);
2153 free(wnamebuf);
2154 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002155 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002156 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002157 return d;
2158 }
2159 /* Drop the argument parsing error as narrow strings
2160 are also valid. */
2161 PyErr_Clear();
2162 }
2163#endif
2164
Tim Peters5aa91602002-01-30 05:46:57 +00002165 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002166 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002167 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002168 if (len > 0) {
2169 char ch = namebuf[len-1];
2170 if (ch != SEP && ch != ALTSEP && ch != ':')
2171 namebuf[len++] = '/';
2172 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002173 strcpy(namebuf + len, "*.*");
2174
Barry Warsaw53699e91996-12-10 23:23:01 +00002175 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002176 return NULL;
2177
2178 hFindFile = FindFirstFile(namebuf, &FileData);
2179 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002180 int error = GetLastError();
2181 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002182 return d;
2183 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002184 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002185 }
2186 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002187 /* Skip over . and .. */
2188 if (strcmp(FileData.cFileName, ".") != 0 &&
2189 strcmp(FileData.cFileName, "..") != 0) {
Christian Heimes72b710a2008-05-26 13:28:38 +00002190 v = PyBytes_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002191 if (v == NULL) {
2192 Py_DECREF(d);
2193 d = NULL;
2194 break;
2195 }
2196 if (PyList_Append(d, v) != 0) {
2197 Py_DECREF(v);
2198 Py_DECREF(d);
2199 d = NULL;
2200 break;
2201 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002202 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002203 }
Georg Brandl622927b2006-03-07 12:48:03 +00002204 Py_BEGIN_ALLOW_THREADS
2205 result = FindNextFile(hFindFile, &FileData);
2206 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002207 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2208 it got to the end of the directory. */
2209 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2210 Py_DECREF(d);
2211 win32_error("FindNextFile", namebuf);
2212 FindClose(hFindFile);
2213 return NULL;
2214 }
Georg Brandl622927b2006-03-07 12:48:03 +00002215 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002216
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002217 if (FindClose(hFindFile) == FALSE) {
2218 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002219 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002220 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002221
2222 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002223
Tim Peters0bb44a42000-09-15 07:44:49 +00002224#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002225
2226#ifndef MAX_PATH
2227#define MAX_PATH CCHMAXPATH
2228#endif
2229 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002230 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002231 PyObject *d, *v;
2232 char namebuf[MAX_PATH+5];
2233 HDIR hdir = 1;
2234 ULONG srchcnt = 1;
2235 FILEFINDBUF3 ep;
2236 APIRET rc;
2237
Alexandre Vassalotti70a23712007-10-14 02:05:51 +00002238 if (!PyArg_ParseTuple(args, "et#:listdir",
2239 Py_FileSystemDefaultEncoding, &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002240 return NULL;
2241 if (len >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00002242 PyMem_Free(name);
2243 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002244 return NULL;
2245 }
2246 strcpy(namebuf, name);
2247 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002248 if (*pt == ALTSEP)
2249 *pt = SEP;
2250 if (namebuf[len-1] != SEP)
2251 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002252 strcpy(namebuf + len, "*.*");
2253
Neal Norwitz6c913782007-10-14 03:23:09 +00002254 if ((d = PyList_New(0)) == NULL) {
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002255 PyMem_Free(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002256 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002257 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002258
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002259 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2260 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002261 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002262 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2263 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2264 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002265
2266 if (rc != NO_ERROR) {
2267 errno = ENOENT;
Neal Norwitz6c913782007-10-14 03:23:09 +00002268 return posix_error_with_allocated_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002269 }
2270
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002271 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002272 do {
2273 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002274 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002275 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002276
2277 strcpy(namebuf, ep.achName);
2278
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002279 /* Leave Case of Name Alone -- In Native Form */
2280 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002281
Christian Heimes72b710a2008-05-26 13:28:38 +00002282 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002283 if (v == NULL) {
2284 Py_DECREF(d);
2285 d = NULL;
2286 break;
2287 }
2288 if (PyList_Append(d, v) != 0) {
2289 Py_DECREF(v);
2290 Py_DECREF(d);
2291 d = NULL;
2292 break;
2293 }
2294 Py_DECREF(v);
2295 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2296 }
2297
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002298 PyMem_Free(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002299 return d;
2300#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002301
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002302 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002303 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002304 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002305 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002306 int arg_is_unicode = 1;
2307
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002308 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002309 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2310 arg_is_unicode = 0;
2311 PyErr_Clear();
2312 }
2313 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002314 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002315 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002316 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002317 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002318 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002319 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002320 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002321 return NULL;
2322 }
Georg Brandl622927b2006-03-07 12:48:03 +00002323 for (;;) {
Georg Brandl3dbca812008-07-23 16:10:53 +00002324 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002325 Py_BEGIN_ALLOW_THREADS
2326 ep = readdir(dirp);
2327 Py_END_ALLOW_THREADS
Georg Brandl3dbca812008-07-23 16:10:53 +00002328 if (ep == NULL) {
2329 if (errno == 0) {
2330 break;
2331 } else {
2332 closedir(dirp);
2333 Py_DECREF(d);
2334 return posix_error_with_allocated_filename(name);
2335 }
2336 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002337 if (ep->d_name[0] == '.' &&
2338 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002339 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002340 continue;
Christian Heimes72b710a2008-05-26 13:28:38 +00002341 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002342 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002343 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002344 d = NULL;
2345 break;
2346 }
Just van Rossum96b1c902003-03-03 17:32:15 +00002347 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002348 PyObject *w;
2349
2350 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002351 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002352 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002353 if (w != NULL) {
2354 Py_DECREF(v);
2355 v = w;
2356 }
2357 else {
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002358 /* Ignore undecodable filenames, as discussed
2359 * in issue 3187. To include these,
2360 * use getcwdb(). */
Just van Rossum6a421832003-03-04 19:30:44 +00002361 PyErr_Clear();
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002362 Py_DECREF(v);
2363 continue;
Just van Rossum46c97842003-02-25 21:42:15 +00002364 }
Just van Rossum46c97842003-02-25 21:42:15 +00002365 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002366 if (PyList_Append(d, v) != 0) {
2367 Py_DECREF(v);
2368 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002369 d = NULL;
2370 break;
2371 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002372 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002373 }
2374 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002375 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002376
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002377 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002378
Tim Peters0bb44a42000-09-15 07:44:49 +00002379#endif /* which OS */
2380} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002381
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002382#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002383/* A helper function for abspath on win32 */
2384static PyObject *
2385posix__getfullpathname(PyObject *self, PyObject *args)
2386{
2387 /* assume encoded strings wont more than double no of chars */
2388 char inbuf[MAX_PATH*2];
2389 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002390 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002391 char outbuf[MAX_PATH*2];
2392 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002393#ifdef Py_WIN_WIDE_FILENAMES
2394 if (unicode_file_names()) {
2395 PyUnicodeObject *po;
2396 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2397 Py_UNICODE woutbuf[MAX_PATH*2];
2398 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002399 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002400 sizeof(woutbuf)/sizeof(woutbuf[0]),
2401 woutbuf, &wtemp))
2402 return win32_error("GetFullPathName", "");
2403 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2404 }
2405 /* Drop the argument parsing error as narrow strings
2406 are also valid. */
2407 PyErr_Clear();
2408 }
2409#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002410 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2411 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002412 &insize))
2413 return NULL;
2414 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2415 outbuf, &temp))
2416 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002417 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2418 return PyUnicode_Decode(outbuf, strlen(outbuf),
2419 Py_FileSystemDefaultEncoding, NULL);
2420 }
Christian Heimes72b710a2008-05-26 13:28:38 +00002421 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002422} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002423#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002424
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002425PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002426"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002427Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002428
Barry Warsaw53699e91996-12-10 23:23:01 +00002429static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002430posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002431{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002432 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002433 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002434 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002435
2436#ifdef Py_WIN_WIDE_FILENAMES
2437 if (unicode_file_names()) {
2438 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002439 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002440 Py_BEGIN_ALLOW_THREADS
2441 /* PyUnicode_AS_UNICODE OK without thread lock as
2442 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002443 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002444 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002445 if (!res)
2446 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002447 Py_INCREF(Py_None);
2448 return Py_None;
2449 }
2450 /* Drop the argument parsing error as narrow strings
2451 are also valid. */
2452 PyErr_Clear();
2453 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002454 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2455 Py_FileSystemDefaultEncoding, &path, &mode))
2456 return NULL;
2457 Py_BEGIN_ALLOW_THREADS
2458 /* PyUnicode_AS_UNICODE OK without thread lock as
2459 it is a simple dereference. */
2460 res = CreateDirectoryA(path, NULL);
2461 Py_END_ALLOW_THREADS
2462 if (!res) {
2463 win32_error("mkdir", path);
2464 PyMem_Free(path);
2465 return NULL;
2466 }
2467 PyMem_Free(path);
2468 Py_INCREF(Py_None);
2469 return Py_None;
2470#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002471
Tim Peters5aa91602002-01-30 05:46:57 +00002472 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002473 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002474 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002475 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002476#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002477 res = mkdir(path);
2478#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002479 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002480#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002481 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002482 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002483 return posix_error_with_allocated_filename(path);
2484 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002485 Py_INCREF(Py_None);
2486 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002487#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002488}
2489
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002490
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002491/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2492#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002493#include <sys/resource.h>
2494#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002495
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002496
2497#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002498PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002499"nice(inc) -> new_priority\n\n\
2500Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002501
Barry Warsaw53699e91996-12-10 23:23:01 +00002502static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002503posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002504{
2505 int increment, value;
2506
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002507 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002508 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002509
2510 /* There are two flavours of 'nice': one that returns the new
2511 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002512 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2513 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002514
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002515 If we are of the nice family that returns the new priority, we
2516 need to clear errno before the call, and check if errno is filled
2517 before calling posix_error() on a returnvalue of -1, because the
2518 -1 may be the actual new priority! */
2519
2520 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002521 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002522#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002523 if (value == 0)
2524 value = getpriority(PRIO_PROCESS, 0);
2525#endif
2526 if (value == -1 && errno != 0)
2527 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002528 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00002529 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002530}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002531#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002532
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002533PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002534"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002535Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002536
Barry Warsaw53699e91996-12-10 23:23:01 +00002537static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002538posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002539{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002540#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002541 PyObject *o1, *o2;
2542 char *p1, *p2;
2543 BOOL result;
2544 if (unicode_file_names()) {
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002545 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2546 goto error;
2547 if (!convert_to_unicode(&o1))
2548 goto error;
2549 if (!convert_to_unicode(&o2)) {
2550 Py_DECREF(o1);
2551 goto error;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002552 }
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002553 Py_BEGIN_ALLOW_THREADS
2554 result = MoveFileW(PyUnicode_AsUnicode(o1),
2555 PyUnicode_AsUnicode(o2));
2556 Py_END_ALLOW_THREADS
2557 Py_DECREF(o1);
2558 Py_DECREF(o2);
2559 if (!result)
2560 return win32_error("rename", NULL);
2561 Py_INCREF(Py_None);
2562 return Py_None;
2563error:
2564 PyErr_Clear();
Thomas Wouters477c8d52006-05-27 19:21:47 +00002565 }
2566 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2567 return NULL;
2568 Py_BEGIN_ALLOW_THREADS
2569 result = MoveFileA(p1, p2);
2570 Py_END_ALLOW_THREADS
2571 if (!result)
2572 return win32_error("rename", NULL);
2573 Py_INCREF(Py_None);
2574 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002575#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002576 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002577#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002578}
2579
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002580
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002581PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002582"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002583Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002584
Barry Warsaw53699e91996-12-10 23:23:01 +00002585static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002586posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002587{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002588#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002589 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002590#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002591 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002592#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002593}
2594
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002595
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002596PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002597"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002598Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002599
Barry Warsaw53699e91996-12-10 23:23:01 +00002600static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002601posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002602{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002603#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002604 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002605#else
2606 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2607#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002608}
2609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002610
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002611#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002612PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002613"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002614Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002615
Barry Warsaw53699e91996-12-10 23:23:01 +00002616static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002617posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002618{
Guido van Rossumff4949e1992-08-05 19:58:53 +00002619 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002620#ifdef MS_WINDOWS
2621 wchar_t *command;
2622 if (!PyArg_ParseTuple(args, "u:system", &command))
2623 return NULL;
2624#else
2625 char *command;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002626 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002627 return NULL;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002628#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002629 Py_BEGIN_ALLOW_THREADS
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002630#ifdef MS_WINDOWS
2631 sts = _wsystem(command);
2632#else
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002633 sts = system(command);
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002634#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002635 Py_END_ALLOW_THREADS
Christian Heimes217cfd12007-12-02 14:31:20 +00002636 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002637}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002638#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002639
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002640
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002641PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002642"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002643Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002644
Barry Warsaw53699e91996-12-10 23:23:01 +00002645static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002646posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002647{
2648 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002649 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002650 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002651 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002652 if (i < 0)
2653 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00002654 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002655}
2656
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002657
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002658PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002659"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002660Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002661
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002662PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002663"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002664Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002665
Barry Warsaw53699e91996-12-10 23:23:01 +00002666static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002667posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002668{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002669#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002670 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002671#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002672 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002673#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002674}
2675
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002676
Guido van Rossumb6775db1994-08-01 11:34:53 +00002677#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002678PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002679"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002680Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002681
Barry Warsaw53699e91996-12-10 23:23:01 +00002682static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002683posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002684{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002685 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002686 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002687
Barry Warsaw53699e91996-12-10 23:23:01 +00002688 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002689 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002690 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002691 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002692 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002693 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002694 u.sysname,
2695 u.nodename,
2696 u.release,
2697 u.version,
2698 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002699}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002700#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002701
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002702static int
2703extract_time(PyObject *t, long* sec, long* usec)
2704{
2705 long intval;
2706 if (PyFloat_Check(t)) {
2707 double tval = PyFloat_AsDouble(t);
Christian Heimes90aa7642007-12-19 02:45:37 +00002708 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002709 if (!intobj)
2710 return -1;
Christian Heimes217cfd12007-12-02 14:31:20 +00002711 intval = PyLong_AsLong(intobj);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002712 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002713 if (intval == -1 && PyErr_Occurred())
2714 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002715 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002716 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002717 if (*usec < 0)
2718 /* If rounding gave us a negative number,
2719 truncate. */
2720 *usec = 0;
2721 return 0;
2722 }
Christian Heimes217cfd12007-12-02 14:31:20 +00002723 intval = PyLong_AsLong(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002724 if (intval == -1 && PyErr_Occurred())
2725 return -1;
2726 *sec = intval;
2727 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002728 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002729}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002730
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002731PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002732"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002733utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002734Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002735second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002736
Barry Warsaw53699e91996-12-10 23:23:01 +00002737static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002738posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002739{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002740#ifdef Py_WIN_WIDE_FILENAMES
2741 PyObject *arg;
2742 PyUnicodeObject *obwpath;
2743 wchar_t *wpath = NULL;
2744 char *apath = NULL;
2745 HANDLE hFile;
2746 long atimesec, mtimesec, ausec, musec;
2747 FILETIME atime, mtime;
2748 PyObject *result = NULL;
2749
2750 if (unicode_file_names()) {
2751 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2752 wpath = PyUnicode_AS_UNICODE(obwpath);
2753 Py_BEGIN_ALLOW_THREADS
2754 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002755 NULL, OPEN_EXISTING,
2756 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002757 Py_END_ALLOW_THREADS
2758 if (hFile == INVALID_HANDLE_VALUE)
2759 return win32_error_unicode("utime", wpath);
2760 } else
2761 /* Drop the argument parsing error as narrow strings
2762 are also valid. */
2763 PyErr_Clear();
2764 }
2765 if (!wpath) {
2766 if (!PyArg_ParseTuple(args, "etO:utime",
2767 Py_FileSystemDefaultEncoding, &apath, &arg))
2768 return NULL;
2769 Py_BEGIN_ALLOW_THREADS
2770 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002771 NULL, OPEN_EXISTING,
2772 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002773 Py_END_ALLOW_THREADS
2774 if (hFile == INVALID_HANDLE_VALUE) {
2775 win32_error("utime", apath);
2776 PyMem_Free(apath);
2777 return NULL;
2778 }
2779 PyMem_Free(apath);
2780 }
2781
2782 if (arg == Py_None) {
2783 SYSTEMTIME now;
2784 GetSystemTime(&now);
2785 if (!SystemTimeToFileTime(&now, &mtime) ||
2786 !SystemTimeToFileTime(&now, &atime)) {
2787 win32_error("utime", NULL);
2788 goto done;
2789 }
2790 }
2791 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2792 PyErr_SetString(PyExc_TypeError,
2793 "utime() arg 2 must be a tuple (atime, mtime)");
2794 goto done;
2795 }
2796 else {
2797 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2798 &atimesec, &ausec) == -1)
2799 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002800 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002801 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2802 &mtimesec, &musec) == -1)
2803 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002804 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002805 }
2806 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2807 /* Avoid putting the file name into the error here,
2808 as that may confuse the user into believing that
2809 something is wrong with the file, when it also
2810 could be the time stamp that gives a problem. */
2811 win32_error("utime", NULL);
2812 }
2813 Py_INCREF(Py_None);
2814 result = Py_None;
2815done:
2816 CloseHandle(hFile);
2817 return result;
2818#else /* Py_WIN_WIDE_FILENAMES */
2819
Neal Norwitz2adf2102004-06-09 01:46:02 +00002820 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002821 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002822 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002823 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002824
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002825#if defined(HAVE_UTIMES)
2826 struct timeval buf[2];
2827#define ATIME buf[0].tv_sec
2828#define MTIME buf[1].tv_sec
2829#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002830/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002831 struct utimbuf buf;
2832#define ATIME buf.actime
2833#define MTIME buf.modtime
2834#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002835#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002836 time_t buf[2];
2837#define ATIME buf[0]
2838#define MTIME buf[1]
2839#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002840#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002841
Mark Hammond817c9292003-12-03 01:22:38 +00002842
Thomas Wouters477c8d52006-05-27 19:21:47 +00002843 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002844 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002845 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002846 if (arg == Py_None) {
2847 /* optional time values not given */
2848 Py_BEGIN_ALLOW_THREADS
2849 res = utime(path, NULL);
2850 Py_END_ALLOW_THREADS
2851 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002852 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002853 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002854 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002855 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002856 return NULL;
2857 }
2858 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002859 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002860 &atime, &ausec) == -1) {
2861 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002862 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002863 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002864 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002865 &mtime, &musec) == -1) {
2866 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002867 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002868 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002869 ATIME = atime;
2870 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002871#ifdef HAVE_UTIMES
2872 buf[0].tv_usec = ausec;
2873 buf[1].tv_usec = musec;
2874 Py_BEGIN_ALLOW_THREADS
2875 res = utimes(path, buf);
2876 Py_END_ALLOW_THREADS
2877#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002878 Py_BEGIN_ALLOW_THREADS
2879 res = utime(path, UTIME_ARG);
2880 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002881#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002882 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002883 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002884 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002885 }
Neal Norwitz96652712004-06-06 20:40:27 +00002886 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002887 Py_INCREF(Py_None);
2888 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002889#undef UTIME_ARG
2890#undef ATIME
2891#undef MTIME
Thomas Wouters477c8d52006-05-27 19:21:47 +00002892#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002893}
2894
Guido van Rossum85e3b011991-06-03 12:42:10 +00002895
Guido van Rossum3b066191991-06-04 19:40:25 +00002896/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002897
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002898PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002899"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002900Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002901
Barry Warsaw53699e91996-12-10 23:23:01 +00002902static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002903posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002904{
2905 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002906 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002907 return NULL;
2908 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002909 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002910}
2911
Martin v. Löwis114619e2002-10-07 06:44:21 +00002912#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2913static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002914free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002915{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002916 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002917 for (i = 0; i < count; i++)
2918 PyMem_Free(array[i]);
2919 PyMem_DEL(array);
2920}
2921#endif
2922
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002923
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002924#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002925PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002926"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002927Execute an executable path with arguments, replacing current process.\n\
2928\n\
2929 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002930 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002931
Barry Warsaw53699e91996-12-10 23:23:01 +00002932static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002933posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002934{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002935 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002936 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002937 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002938 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002939 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002940
Guido van Rossum89b33251993-10-22 14:26:06 +00002941 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002942 argv is a list or tuple of strings. */
2943
Martin v. Löwis114619e2002-10-07 06:44:21 +00002944 if (!PyArg_ParseTuple(args, "etO:execv",
2945 Py_FileSystemDefaultEncoding,
2946 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002947 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002948 if (PyList_Check(argv)) {
2949 argc = PyList_Size(argv);
2950 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002951 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002952 else if (PyTuple_Check(argv)) {
2953 argc = PyTuple_Size(argv);
2954 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002955 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002956 else {
Fred Drake661ea262000-10-24 19:57:45 +00002957 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002958 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002959 return NULL;
2960 }
Thomas Heller6790d602007-08-30 17:15:14 +00002961 if (argc < 1) {
2962 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
2963 PyMem_Free(path);
2964 return NULL;
2965 }
Guido van Rossum50422b42000-04-26 20:34:28 +00002966
Barry Warsaw53699e91996-12-10 23:23:01 +00002967 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002968 if (argvlist == NULL) {
2969 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002970 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002971 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002972 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002973 if (!PyArg_Parse((*getitem)(argv, i), "et",
2974 Py_FileSystemDefaultEncoding,
2975 &argvlist[i])) {
2976 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002977 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002978 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002979 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002980 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002981
Guido van Rossum85e3b011991-06-03 12:42:10 +00002982 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002983 }
2984 argvlist[argc] = NULL;
2985
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002986 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002987
Guido van Rossum85e3b011991-06-03 12:42:10 +00002988 /* If we get here it's definitely an error */
2989
Martin v. Löwis114619e2002-10-07 06:44:21 +00002990 free_string_array(argvlist, argc);
2991 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002992 return posix_error();
2993}
2994
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002995
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002996PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002997"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002998Execute a path with arguments and environment, replacing current process.\n\
2999\n\
3000 path: path of executable file\n\
3001 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003002 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003003
Barry Warsaw53699e91996-12-10 23:23:01 +00003004static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003005posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003006{
3007 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003008 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003009 char **argvlist;
3010 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003011 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003012 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003013 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003014 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003015
3016 /* execve has three arguments: (path, argv, env), where
3017 argv is a list or tuple of strings and env is a dictionary
3018 like posix.environ. */
3019
Martin v. Löwis114619e2002-10-07 06:44:21 +00003020 if (!PyArg_ParseTuple(args, "etOO:execve",
3021 Py_FileSystemDefaultEncoding,
3022 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003023 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003024 if (PyList_Check(argv)) {
3025 argc = PyList_Size(argv);
3026 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003027 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003028 else if (PyTuple_Check(argv)) {
3029 argc = PyTuple_Size(argv);
3030 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003031 }
3032 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003033 PyErr_SetString(PyExc_TypeError,
3034 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003035 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003036 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003037 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003038 PyErr_SetString(PyExc_TypeError,
3039 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003040 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003041 }
3042
Barry Warsaw53699e91996-12-10 23:23:01 +00003043 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003044 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003045 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003046 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003047 }
3048 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003049 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003050 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003051 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003052 &argvlist[i]))
3053 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003054 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003055 goto fail_1;
3056 }
3057 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003058 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003059 argvlist[argc] = NULL;
3060
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003061 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003062 if (i < 0)
3063 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003064 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003065 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003066 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003067 goto fail_1;
3068 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003069 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003070 keys = PyMapping_Keys(env);
3071 vals = PyMapping_Values(env);
3072 if (!keys || !vals)
3073 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003074 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3075 PyErr_SetString(PyExc_TypeError,
3076 "execve(): env.keys() or env.values() is not a list");
3077 goto fail_2;
3078 }
Tim Peters5aa91602002-01-30 05:46:57 +00003079
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003080 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003081 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003082 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003083
3084 key = PyList_GetItem(keys, pos);
3085 val = PyList_GetItem(vals, pos);
3086 if (!key || !val)
3087 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003088
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003089 if (!PyArg_Parse(
3090 key,
3091 "s;execve() arg 3 contains a non-string key",
3092 &k) ||
3093 !PyArg_Parse(
3094 val,
3095 "s;execve() arg 3 contains a non-string value",
3096 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003097 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003098 goto fail_2;
3099 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003100
3101#if defined(PYOS_OS2)
3102 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3103 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3104#endif
Christian Heimes830a4bc2007-11-22 07:43:40 +00003105 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003106 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003107 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003108 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003109 goto fail_2;
3110 }
Tim Petersc8996f52001-12-03 20:41:00 +00003111 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003112 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003113#if defined(PYOS_OS2)
3114 }
3115#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003116 }
3117 envlist[envc] = 0;
3118
3119 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003120
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003121 /* If we get here it's definitely an error */
3122
3123 (void) posix_error();
3124
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003125 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003126 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003127 PyMem_DEL(envlist[envc]);
3128 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003129 fail_1:
3130 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003131 Py_XDECREF(vals);
3132 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003133 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003134 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003135 return NULL;
3136}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003137#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003138
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003139
Guido van Rossuma1065681999-01-25 23:20:23 +00003140#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003141PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003142"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003143Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003144\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003145 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003146 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003147 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003148
3149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003150posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003151{
3152 char *path;
3153 PyObject *argv;
3154 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003155 int mode, i;
3156 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003157 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003158 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003159
3160 /* spawnv has three arguments: (mode, path, argv), where
3161 argv is a list or tuple of strings. */
3162
Martin v. Löwis114619e2002-10-07 06:44:21 +00003163 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3164 Py_FileSystemDefaultEncoding,
3165 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003166 return NULL;
3167 if (PyList_Check(argv)) {
3168 argc = PyList_Size(argv);
3169 getitem = PyList_GetItem;
3170 }
3171 else if (PyTuple_Check(argv)) {
3172 argc = PyTuple_Size(argv);
3173 getitem = PyTuple_GetItem;
3174 }
3175 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003176 PyErr_SetString(PyExc_TypeError,
3177 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003178 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003179 return NULL;
3180 }
3181
3182 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003183 if (argvlist == NULL) {
3184 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003185 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003186 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003187 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003188 if (!PyArg_Parse((*getitem)(argv, i), "et",
3189 Py_FileSystemDefaultEncoding,
3190 &argvlist[i])) {
3191 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003192 PyErr_SetString(
3193 PyExc_TypeError,
3194 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003195 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003196 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003197 }
3198 }
3199 argvlist[argc] = NULL;
3200
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003201#if defined(PYOS_OS2) && defined(PYCC_GCC)
3202 Py_BEGIN_ALLOW_THREADS
3203 spawnval = spawnv(mode, path, argvlist);
3204 Py_END_ALLOW_THREADS
3205#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003206 if (mode == _OLD_P_OVERLAY)
3207 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003208
Tim Peters25059d32001-12-07 20:35:43 +00003209 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003210 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003211 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003212#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003213
Martin v. Löwis114619e2002-10-07 06:44:21 +00003214 free_string_array(argvlist, argc);
3215 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003216
Fred Drake699f3522000-06-29 21:12:41 +00003217 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003218 return posix_error();
3219 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003220#if SIZEOF_LONG == SIZEOF_VOID_P
3221 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003222#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003223 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003224#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003225}
3226
3227
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003228PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003229"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003230Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003231\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003232 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003233 path: path of executable file\n\
3234 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003235 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003236
3237static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003238posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003239{
3240 char *path;
3241 PyObject *argv, *env;
3242 char **argvlist;
3243 char **envlist;
3244 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003245 int mode, pos, envc;
3246 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003247 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003248 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003249 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003250
3251 /* spawnve has four arguments: (mode, path, argv, env), where
3252 argv is a list or tuple of strings and env is a dictionary
3253 like posix.environ. */
3254
Martin v. Löwis114619e2002-10-07 06:44:21 +00003255 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3256 Py_FileSystemDefaultEncoding,
3257 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003258 return NULL;
3259 if (PyList_Check(argv)) {
3260 argc = PyList_Size(argv);
3261 getitem = PyList_GetItem;
3262 }
3263 else if (PyTuple_Check(argv)) {
3264 argc = PyTuple_Size(argv);
3265 getitem = PyTuple_GetItem;
3266 }
3267 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003268 PyErr_SetString(PyExc_TypeError,
3269 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003270 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003271 }
3272 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003273 PyErr_SetString(PyExc_TypeError,
3274 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003275 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003276 }
3277
3278 argvlist = PyMem_NEW(char *, argc+1);
3279 if (argvlist == NULL) {
3280 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003281 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003282 }
3283 for (i = 0; i < argc; i++) {
3284 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003285 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003286 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003287 &argvlist[i]))
3288 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003289 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003290 goto fail_1;
3291 }
3292 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003293 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003294 argvlist[argc] = NULL;
3295
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003296 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003297 if (i < 0)
3298 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003299 envlist = PyMem_NEW(char *, i + 1);
3300 if (envlist == NULL) {
3301 PyErr_NoMemory();
3302 goto fail_1;
3303 }
3304 envc = 0;
3305 keys = PyMapping_Keys(env);
3306 vals = PyMapping_Values(env);
3307 if (!keys || !vals)
3308 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003309 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3310 PyErr_SetString(PyExc_TypeError,
3311 "spawnve(): env.keys() or env.values() is not a list");
3312 goto fail_2;
3313 }
Tim Peters5aa91602002-01-30 05:46:57 +00003314
Guido van Rossuma1065681999-01-25 23:20:23 +00003315 for (pos = 0; pos < i; pos++) {
3316 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003317 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003318
3319 key = PyList_GetItem(keys, pos);
3320 val = PyList_GetItem(vals, pos);
3321 if (!key || !val)
3322 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003323
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003324 if (!PyArg_Parse(
3325 key,
3326 "s;spawnve() arg 3 contains a non-string key",
3327 &k) ||
3328 !PyArg_Parse(
3329 val,
3330 "s;spawnve() arg 3 contains a non-string value",
3331 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003332 {
3333 goto fail_2;
3334 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003335 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003336 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003337 if (p == NULL) {
3338 PyErr_NoMemory();
3339 goto fail_2;
3340 }
Tim Petersc8996f52001-12-03 20:41:00 +00003341 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003342 envlist[envc++] = p;
3343 }
3344 envlist[envc] = 0;
3345
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003346#if defined(PYOS_OS2) && defined(PYCC_GCC)
3347 Py_BEGIN_ALLOW_THREADS
3348 spawnval = spawnve(mode, path, argvlist, envlist);
3349 Py_END_ALLOW_THREADS
3350#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003351 if (mode == _OLD_P_OVERLAY)
3352 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003353
3354 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003355 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003356 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003357#endif
Tim Peters25059d32001-12-07 20:35:43 +00003358
Fred Drake699f3522000-06-29 21:12:41 +00003359 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003360 (void) posix_error();
3361 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003362#if SIZEOF_LONG == SIZEOF_VOID_P
3363 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003364#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003365 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003366#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003367
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003368 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003369 while (--envc >= 0)
3370 PyMem_DEL(envlist[envc]);
3371 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003372 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003373 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003374 Py_XDECREF(vals);
3375 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003376 fail_0:
3377 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003378 return res;
3379}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003380
3381/* OS/2 supports spawnvp & spawnvpe natively */
3382#if defined(PYOS_OS2)
3383PyDoc_STRVAR(posix_spawnvp__doc__,
3384"spawnvp(mode, file, args)\n\n\
3385Execute the program 'file' in a new process, using the environment\n\
3386search path to find the file.\n\
3387\n\
3388 mode: mode of process creation\n\
3389 file: executable file name\n\
3390 args: tuple or list of strings");
3391
3392static PyObject *
3393posix_spawnvp(PyObject *self, PyObject *args)
3394{
3395 char *path;
3396 PyObject *argv;
3397 char **argvlist;
3398 int mode, i, argc;
3399 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003400 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003401
3402 /* spawnvp has three arguments: (mode, path, argv), where
3403 argv is a list or tuple of strings. */
3404
3405 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3406 Py_FileSystemDefaultEncoding,
3407 &path, &argv))
3408 return NULL;
3409 if (PyList_Check(argv)) {
3410 argc = PyList_Size(argv);
3411 getitem = PyList_GetItem;
3412 }
3413 else if (PyTuple_Check(argv)) {
3414 argc = PyTuple_Size(argv);
3415 getitem = PyTuple_GetItem;
3416 }
3417 else {
3418 PyErr_SetString(PyExc_TypeError,
3419 "spawnvp() arg 2 must be a tuple or list");
3420 PyMem_Free(path);
3421 return NULL;
3422 }
3423
3424 argvlist = PyMem_NEW(char *, argc+1);
3425 if (argvlist == NULL) {
3426 PyMem_Free(path);
3427 return PyErr_NoMemory();
3428 }
3429 for (i = 0; i < argc; i++) {
3430 if (!PyArg_Parse((*getitem)(argv, i), "et",
3431 Py_FileSystemDefaultEncoding,
3432 &argvlist[i])) {
3433 free_string_array(argvlist, i);
3434 PyErr_SetString(
3435 PyExc_TypeError,
3436 "spawnvp() arg 2 must contain only strings");
3437 PyMem_Free(path);
3438 return NULL;
3439 }
3440 }
3441 argvlist[argc] = NULL;
3442
3443 Py_BEGIN_ALLOW_THREADS
3444#if defined(PYCC_GCC)
3445 spawnval = spawnvp(mode, path, argvlist);
3446#else
3447 spawnval = _spawnvp(mode, path, argvlist);
3448#endif
3449 Py_END_ALLOW_THREADS
3450
3451 free_string_array(argvlist, argc);
3452 PyMem_Free(path);
3453
3454 if (spawnval == -1)
3455 return posix_error();
3456 else
3457 return Py_BuildValue("l", (long) spawnval);
3458}
3459
3460
3461PyDoc_STRVAR(posix_spawnvpe__doc__,
3462"spawnvpe(mode, file, args, env)\n\n\
3463Execute the program 'file' in a new process, using the environment\n\
3464search path to find the file.\n\
3465\n\
3466 mode: mode of process creation\n\
3467 file: executable file name\n\
3468 args: tuple or list of arguments\n\
3469 env: dictionary of strings mapping to strings");
3470
3471static PyObject *
3472posix_spawnvpe(PyObject *self, PyObject *args)
3473{
3474 char *path;
3475 PyObject *argv, *env;
3476 char **argvlist;
3477 char **envlist;
3478 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3479 int mode, i, pos, argc, envc;
3480 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003481 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003482 int lastarg = 0;
3483
3484 /* spawnvpe has four arguments: (mode, path, argv, env), where
3485 argv is a list or tuple of strings and env is a dictionary
3486 like posix.environ. */
3487
3488 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3489 Py_FileSystemDefaultEncoding,
3490 &path, &argv, &env))
3491 return NULL;
3492 if (PyList_Check(argv)) {
3493 argc = PyList_Size(argv);
3494 getitem = PyList_GetItem;
3495 }
3496 else if (PyTuple_Check(argv)) {
3497 argc = PyTuple_Size(argv);
3498 getitem = PyTuple_GetItem;
3499 }
3500 else {
3501 PyErr_SetString(PyExc_TypeError,
3502 "spawnvpe() arg 2 must be a tuple or list");
3503 goto fail_0;
3504 }
3505 if (!PyMapping_Check(env)) {
3506 PyErr_SetString(PyExc_TypeError,
3507 "spawnvpe() arg 3 must be a mapping object");
3508 goto fail_0;
3509 }
3510
3511 argvlist = PyMem_NEW(char *, argc+1);
3512 if (argvlist == NULL) {
3513 PyErr_NoMemory();
3514 goto fail_0;
3515 }
3516 for (i = 0; i < argc; i++) {
3517 if (!PyArg_Parse((*getitem)(argv, i),
3518 "et;spawnvpe() arg 2 must contain only strings",
3519 Py_FileSystemDefaultEncoding,
3520 &argvlist[i]))
3521 {
3522 lastarg = i;
3523 goto fail_1;
3524 }
3525 }
3526 lastarg = argc;
3527 argvlist[argc] = NULL;
3528
3529 i = PyMapping_Size(env);
3530 if (i < 0)
3531 goto fail_1;
3532 envlist = PyMem_NEW(char *, i + 1);
3533 if (envlist == NULL) {
3534 PyErr_NoMemory();
3535 goto fail_1;
3536 }
3537 envc = 0;
3538 keys = PyMapping_Keys(env);
3539 vals = PyMapping_Values(env);
3540 if (!keys || !vals)
3541 goto fail_2;
3542 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3543 PyErr_SetString(PyExc_TypeError,
3544 "spawnvpe(): env.keys() or env.values() is not a list");
3545 goto fail_2;
3546 }
3547
3548 for (pos = 0; pos < i; pos++) {
3549 char *p, *k, *v;
3550 size_t len;
3551
3552 key = PyList_GetItem(keys, pos);
3553 val = PyList_GetItem(vals, pos);
3554 if (!key || !val)
3555 goto fail_2;
3556
3557 if (!PyArg_Parse(
3558 key,
3559 "s;spawnvpe() arg 3 contains a non-string key",
3560 &k) ||
3561 !PyArg_Parse(
3562 val,
3563 "s;spawnvpe() arg 3 contains a non-string value",
3564 &v))
3565 {
3566 goto fail_2;
3567 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003568 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003569 p = PyMem_NEW(char, len);
3570 if (p == NULL) {
3571 PyErr_NoMemory();
3572 goto fail_2;
3573 }
3574 PyOS_snprintf(p, len, "%s=%s", k, v);
3575 envlist[envc++] = p;
3576 }
3577 envlist[envc] = 0;
3578
3579 Py_BEGIN_ALLOW_THREADS
3580#if defined(PYCC_GCC)
Christian Heimes292d3512008-02-03 16:51:08 +00003581 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003582#else
Christian Heimes292d3512008-02-03 16:51:08 +00003583 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003584#endif
3585 Py_END_ALLOW_THREADS
3586
3587 if (spawnval == -1)
3588 (void) posix_error();
3589 else
3590 res = Py_BuildValue("l", (long) spawnval);
3591
3592 fail_2:
3593 while (--envc >= 0)
3594 PyMem_DEL(envlist[envc]);
3595 PyMem_DEL(envlist);
3596 fail_1:
3597 free_string_array(argvlist, lastarg);
3598 Py_XDECREF(vals);
3599 Py_XDECREF(keys);
3600 fail_0:
3601 PyMem_Free(path);
3602 return res;
3603}
3604#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003605#endif /* HAVE_SPAWNV */
3606
3607
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003608#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003609PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003610"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003611Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3612\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003613Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003614
3615static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003616posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003617{
Christian Heimes400adb02008-02-01 08:12:03 +00003618 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003619 if (pid == -1)
3620 return posix_error();
Georg Brandl2ee470f2008-07-16 12:55:28 +00003621 if (pid == 0)
3622 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003623 return PyLong_FromLong(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003624}
3625#endif
3626
3627
Guido van Rossumad0ee831995-03-01 10:34:45 +00003628#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003629PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003630"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003631Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003632Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003633
Barry Warsaw53699e91996-12-10 23:23:01 +00003634static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003635posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003636{
Christian Heimes400adb02008-02-01 08:12:03 +00003637 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003638 if (pid == -1)
3639 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003640 if (pid == 0)
3641 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003642 return PyLong_FromLong(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003643}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003644#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003645
Neal Norwitzb59798b2003-03-21 01:43:31 +00003646/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003647/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3648#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003649#define DEV_PTY_FILE "/dev/ptc"
3650#define HAVE_DEV_PTMX
3651#else
3652#define DEV_PTY_FILE "/dev/ptmx"
3653#endif
3654
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003655#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003656#ifdef HAVE_PTY_H
3657#include <pty.h>
3658#else
3659#ifdef HAVE_LIBUTIL_H
3660#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003661#endif /* HAVE_LIBUTIL_H */
3662#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003663#ifdef HAVE_STROPTS_H
3664#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003665#endif
3666#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003667
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003668#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003669PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003670"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003671Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003672
3673static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003674posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003675{
3676 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003677#ifndef HAVE_OPENPTY
3678 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003679#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003680#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003681 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003682#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003683 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003684#endif
3685#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003686
Thomas Wouters70c21a12000-07-14 14:28:33 +00003687#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003688 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3689 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003690#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003691 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3692 if (slave_name == NULL)
3693 return posix_error();
3694
3695 slave_fd = open(slave_name, O_RDWR);
3696 if (slave_fd < 0)
3697 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003698#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003699 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003700 if (master_fd < 0)
3701 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003702 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003703 /* change permission of slave */
3704 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003705 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003706 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003707 }
3708 /* unlock slave */
3709 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003710 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003711 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003712 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003713 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003714 slave_name = ptsname(master_fd); /* get name of slave */
3715 if (slave_name == NULL)
3716 return posix_error();
3717 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3718 if (slave_fd < 0)
3719 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003720#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003721 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3722 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003723#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003724 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003725#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003726#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003727#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003728
Fred Drake8cef4cf2000-06-28 16:40:38 +00003729 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003730
Fred Drake8cef4cf2000-06-28 16:40:38 +00003731}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003732#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003733
3734#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003735PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003736"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003737Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3738Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003739To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003740
3741static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003742posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003743{
Christian Heimes400adb02008-02-01 08:12:03 +00003744 int master_fd = -1;
3745 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003746
Fred Drake8cef4cf2000-06-28 16:40:38 +00003747 pid = forkpty(&master_fd, NULL, NULL, NULL);
3748 if (pid == -1)
3749 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003750 if (pid == 0)
3751 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003752 return Py_BuildValue("(li)", pid, master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003753}
3754#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003755
Guido van Rossumad0ee831995-03-01 10:34:45 +00003756#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003757PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003758"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003759Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003760
Barry Warsaw53699e91996-12-10 23:23:01 +00003761static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003762posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003763{
Christian Heimes217cfd12007-12-02 14:31:20 +00003764 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003765}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003766#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003767
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003768
Guido van Rossumad0ee831995-03-01 10:34:45 +00003769#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003770PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003771"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003772Return the current process's effective user 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_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003776{
Christian Heimes217cfd12007-12-02 14:31:20 +00003777 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003778}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003779#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003781
Guido van Rossumad0ee831995-03-01 10:34:45 +00003782#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003783PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003784"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003785Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003786
Barry Warsaw53699e91996-12-10 23:23:01 +00003787static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003788posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003789{
Christian Heimes217cfd12007-12-02 14:31:20 +00003790 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003791}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003792#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003793
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003794
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003795PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003796"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003797Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003798
Barry Warsaw53699e91996-12-10 23:23:01 +00003799static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003800posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003801{
Christian Heimes217cfd12007-12-02 14:31:20 +00003802 return PyLong_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003803}
3804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003805
Fred Drakec9680921999-12-13 16:37:25 +00003806#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003807PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003808"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003809Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003810
3811static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003812posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003813{
3814 PyObject *result = NULL;
3815
Fred Drakec9680921999-12-13 16:37:25 +00003816#ifdef NGROUPS_MAX
3817#define MAX_GROUPS NGROUPS_MAX
3818#else
3819 /* defined to be 16 on Solaris7, so this should be a small number */
3820#define MAX_GROUPS 64
3821#endif
3822 gid_t grouplist[MAX_GROUPS];
3823 int n;
3824
3825 n = getgroups(MAX_GROUPS, grouplist);
3826 if (n < 0)
3827 posix_error();
3828 else {
3829 result = PyList_New(n);
3830 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003831 int i;
3832 for (i = 0; i < n; ++i) {
Christian Heimes217cfd12007-12-02 14:31:20 +00003833 PyObject *o = PyLong_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003834 if (o == NULL) {
3835 Py_DECREF(result);
3836 result = NULL;
3837 break;
3838 }
3839 PyList_SET_ITEM(result, i, o);
3840 }
3841 }
3842 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003843
Fred Drakec9680921999-12-13 16:37:25 +00003844 return result;
3845}
3846#endif
3847
Martin v. Löwis606edc12002-06-13 21:09:11 +00003848#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003849PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003850"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003851Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003852
3853static PyObject *
3854posix_getpgid(PyObject *self, PyObject *args)
3855{
3856 int pid, pgid;
3857 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3858 return NULL;
3859 pgid = getpgid(pid);
3860 if (pgid < 0)
3861 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00003862 return PyLong_FromLong((long)pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00003863}
3864#endif /* HAVE_GETPGID */
3865
3866
Guido van Rossumb6775db1994-08-01 11:34:53 +00003867#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003868PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003869"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003870Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003871
Barry Warsaw53699e91996-12-10 23:23:01 +00003872static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003873posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003874{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003875#ifdef GETPGRP_HAVE_ARG
Christian Heimes217cfd12007-12-02 14:31:20 +00003876 return PyLong_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003877#else /* GETPGRP_HAVE_ARG */
Christian Heimes217cfd12007-12-02 14:31:20 +00003878 return PyLong_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003879#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003880}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003881#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003882
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003883
Guido van Rossumb6775db1994-08-01 11:34:53 +00003884#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003885PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003886"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003887Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003888
Barry Warsaw53699e91996-12-10 23:23:01 +00003889static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003890posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003891{
Guido van Rossum64933891994-10-20 21:56:42 +00003892#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003893 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003894#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003895 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003896#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003897 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003898 Py_INCREF(Py_None);
3899 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003900}
3901
Guido van Rossumb6775db1994-08-01 11:34:53 +00003902#endif /* HAVE_SETPGRP */
3903
Guido van Rossumad0ee831995-03-01 10:34:45 +00003904#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003905PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003906"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003907Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003908
Barry Warsaw53699e91996-12-10 23:23:01 +00003909static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003910posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003911{
Christian Heimes217cfd12007-12-02 14:31:20 +00003912 return PyLong_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003913}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003914#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003915
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003916
Fred Drake12c6e2d1999-12-14 21:25:03 +00003917#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003918PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003919"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003920Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003921
3922static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003923posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003924{
Neal Norwitze241ce82003-02-17 18:17:05 +00003925 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003926 char *name;
3927 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003928
Fred Drakea30680b2000-12-06 21:24:28 +00003929 errno = 0;
3930 name = getlogin();
3931 if (name == NULL) {
3932 if (errno)
3933 posix_error();
3934 else
3935 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003936 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003937 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003938 else
Neal Norwitz93c56822007-08-26 07:10:06 +00003939 result = PyUnicode_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003940 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003941
Fred Drake12c6e2d1999-12-14 21:25:03 +00003942 return result;
3943}
3944#endif
3945
Guido van Rossumad0ee831995-03-01 10:34:45 +00003946#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003947PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003948"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003949Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003950
Barry Warsaw53699e91996-12-10 23:23:01 +00003951static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003952posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003953{
Christian Heimes217cfd12007-12-02 14:31:20 +00003954 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003955}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003956#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003957
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003958
Guido van Rossumad0ee831995-03-01 10:34:45 +00003959#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003960PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003961"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003962Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003963
Barry Warsaw53699e91996-12-10 23:23:01 +00003964static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003965posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003966{
Christian Heimes292d3512008-02-03 16:51:08 +00003967 pid_t pid;
3968 int sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003969 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003970 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003971#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003972 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3973 APIRET rc;
3974 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003975 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003976
3977 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3978 APIRET rc;
3979 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003980 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003981
3982 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003983 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003984#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003985 if (kill(pid, sig) == -1)
3986 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003987#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003988 Py_INCREF(Py_None);
3989 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003990}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003991#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003992
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003993#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003994PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003995"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003996Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003997
3998static PyObject *
3999posix_killpg(PyObject *self, PyObject *args)
4000{
4001 int pgid, sig;
4002 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
4003 return NULL;
4004 if (killpg(pgid, sig) == -1)
4005 return posix_error();
4006 Py_INCREF(Py_None);
4007 return Py_None;
4008}
4009#endif
4010
Guido van Rossumc0125471996-06-28 18:55:32 +00004011#ifdef HAVE_PLOCK
4012
4013#ifdef HAVE_SYS_LOCK_H
4014#include <sys/lock.h>
4015#endif
4016
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004017PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004018"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004019Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004020
Barry Warsaw53699e91996-12-10 23:23:01 +00004021static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004022posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004023{
4024 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004025 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004026 return NULL;
4027 if (plock(op) == -1)
4028 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004029 Py_INCREF(Py_None);
4030 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004031}
4032#endif
4033
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004034
Guido van Rossum3b066191991-06-04 19:40:25 +00004035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004036
Guido van Rossumb6775db1994-08-01 11:34:53 +00004037#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004038PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004039"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004040Set the current process's user id.");
4041
Barry Warsaw53699e91996-12-10 23:23:01 +00004042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004043posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004044{
4045 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004046 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004047 return NULL;
4048 if (setuid(uid) < 0)
4049 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004050 Py_INCREF(Py_None);
4051 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004052}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004053#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004054
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004055
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004056#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004057PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004058"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004059Set the current process's effective user id.");
4060
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004061static PyObject *
4062posix_seteuid (PyObject *self, PyObject *args)
4063{
4064 int euid;
4065 if (!PyArg_ParseTuple(args, "i", &euid)) {
4066 return NULL;
4067 } else if (seteuid(euid) < 0) {
4068 return posix_error();
4069 } else {
4070 Py_INCREF(Py_None);
4071 return Py_None;
4072 }
4073}
4074#endif /* HAVE_SETEUID */
4075
4076#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004077PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004078"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004079Set the current process's effective group id.");
4080
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004081static PyObject *
4082posix_setegid (PyObject *self, PyObject *args)
4083{
4084 int egid;
4085 if (!PyArg_ParseTuple(args, "i", &egid)) {
4086 return NULL;
4087 } else if (setegid(egid) < 0) {
4088 return posix_error();
4089 } else {
4090 Py_INCREF(Py_None);
4091 return Py_None;
4092 }
4093}
4094#endif /* HAVE_SETEGID */
4095
4096#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004097PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004098"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004099Set the current process's real and effective user ids.");
4100
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004101static PyObject *
4102posix_setreuid (PyObject *self, PyObject *args)
4103{
4104 int ruid, euid;
4105 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4106 return NULL;
4107 } else if (setreuid(ruid, euid) < 0) {
4108 return posix_error();
4109 } else {
4110 Py_INCREF(Py_None);
4111 return Py_None;
4112 }
4113}
4114#endif /* HAVE_SETREUID */
4115
4116#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004117PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004118"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004119Set the current process's real and effective group ids.");
4120
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004121static PyObject *
4122posix_setregid (PyObject *self, PyObject *args)
4123{
4124 int rgid, egid;
4125 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4126 return NULL;
4127 } else if (setregid(rgid, egid) < 0) {
4128 return posix_error();
4129 } else {
4130 Py_INCREF(Py_None);
4131 return Py_None;
4132 }
4133}
4134#endif /* HAVE_SETREGID */
4135
Guido van Rossumb6775db1994-08-01 11:34:53 +00004136#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004137PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004138"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004139Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004140
Barry Warsaw53699e91996-12-10 23:23:01 +00004141static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004142posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004143{
4144 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004145 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004146 return NULL;
4147 if (setgid(gid) < 0)
4148 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004149 Py_INCREF(Py_None);
4150 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004151}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004152#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004153
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004154#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004155PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004156"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004157Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004158
4159static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004160posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004161{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004162 int i, len;
4163 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004164
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004165 if (!PySequence_Check(groups)) {
4166 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4167 return NULL;
4168 }
4169 len = PySequence_Size(groups);
4170 if (len > MAX_GROUPS) {
4171 PyErr_SetString(PyExc_ValueError, "too many groups");
4172 return NULL;
4173 }
4174 for(i = 0; i < len; i++) {
4175 PyObject *elem;
4176 elem = PySequence_GetItem(groups, i);
4177 if (!elem)
4178 return NULL;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004179 if (!PyLong_Check(elem)) {
4180 PyErr_SetString(PyExc_TypeError,
4181 "groups must be integers");
4182 Py_DECREF(elem);
4183 return NULL;
4184 } else {
4185 unsigned long x = PyLong_AsUnsignedLong(elem);
4186 if (PyErr_Occurred()) {
4187 PyErr_SetString(PyExc_TypeError,
4188 "group id too big");
Georg Brandla13c2442005-11-22 19:30:31 +00004189 Py_DECREF(elem);
4190 return NULL;
Georg Brandla13c2442005-11-22 19:30:31 +00004191 }
Georg Brandla13c2442005-11-22 19:30:31 +00004192 grouplist[i] = x;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004193 /* read back the value to see if it fitted in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00004194 if (grouplist[i] != x) {
4195 PyErr_SetString(PyExc_TypeError,
4196 "group id too big");
4197 Py_DECREF(elem);
4198 return NULL;
4199 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004200 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004201 Py_DECREF(elem);
4202 }
4203
4204 if (setgroups(len, grouplist) < 0)
4205 return posix_error();
4206 Py_INCREF(Py_None);
4207 return Py_None;
4208}
4209#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004210
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004211#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4212static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004213wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004214{
4215 PyObject *result;
4216 static PyObject *struct_rusage;
4217
4218 if (pid == -1)
4219 return posix_error();
4220
4221 if (struct_rusage == NULL) {
Christian Heimes072c0f12008-01-03 23:01:04 +00004222 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004223 if (m == NULL)
4224 return NULL;
4225 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4226 Py_DECREF(m);
4227 if (struct_rusage == NULL)
4228 return NULL;
4229 }
4230
4231 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4232 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4233 if (!result)
4234 return NULL;
4235
4236#ifndef doubletime
4237#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4238#endif
4239
4240 PyStructSequence_SET_ITEM(result, 0,
4241 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4242 PyStructSequence_SET_ITEM(result, 1,
4243 PyFloat_FromDouble(doubletime(ru->ru_stime)));
4244#define SET_INT(result, index, value)\
Christian Heimes217cfd12007-12-02 14:31:20 +00004245 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004246 SET_INT(result, 2, ru->ru_maxrss);
4247 SET_INT(result, 3, ru->ru_ixrss);
4248 SET_INT(result, 4, ru->ru_idrss);
4249 SET_INT(result, 5, ru->ru_isrss);
4250 SET_INT(result, 6, ru->ru_minflt);
4251 SET_INT(result, 7, ru->ru_majflt);
4252 SET_INT(result, 8, ru->ru_nswap);
4253 SET_INT(result, 9, ru->ru_inblock);
4254 SET_INT(result, 10, ru->ru_oublock);
4255 SET_INT(result, 11, ru->ru_msgsnd);
4256 SET_INT(result, 12, ru->ru_msgrcv);
4257 SET_INT(result, 13, ru->ru_nsignals);
4258 SET_INT(result, 14, ru->ru_nvcsw);
4259 SET_INT(result, 15, ru->ru_nivcsw);
4260#undef SET_INT
4261
4262 if (PyErr_Occurred()) {
4263 Py_DECREF(result);
4264 return NULL;
4265 }
4266
4267 return Py_BuildValue("iiN", pid, status, result);
4268}
4269#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4270
4271#ifdef HAVE_WAIT3
4272PyDoc_STRVAR(posix_wait3__doc__,
4273"wait3(options) -> (pid, status, rusage)\n\n\
4274Wait for completion of a child process.");
4275
4276static PyObject *
4277posix_wait3(PyObject *self, PyObject *args)
4278{
Christian Heimes292d3512008-02-03 16:51:08 +00004279 pid_t pid;
4280 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004281 struct rusage ru;
4282 WAIT_TYPE status;
4283 WAIT_STATUS_INT(status) = 0;
4284
4285 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4286 return NULL;
4287
4288 Py_BEGIN_ALLOW_THREADS
4289 pid = wait3(&status, options, &ru);
4290 Py_END_ALLOW_THREADS
4291
4292 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4293}
4294#endif /* HAVE_WAIT3 */
4295
4296#ifdef HAVE_WAIT4
4297PyDoc_STRVAR(posix_wait4__doc__,
4298"wait4(pid, options) -> (pid, status, rusage)\n\n\
4299Wait for completion of a given child process.");
4300
4301static PyObject *
4302posix_wait4(PyObject *self, PyObject *args)
4303{
Christian Heimes292d3512008-02-03 16:51:08 +00004304 pid_t pid;
4305 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004306 struct rusage ru;
4307 WAIT_TYPE status;
4308 WAIT_STATUS_INT(status) = 0;
4309
4310 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
4311 return NULL;
4312
4313 Py_BEGIN_ALLOW_THREADS
4314 pid = wait4(pid, &status, options, &ru);
4315 Py_END_ALLOW_THREADS
4316
4317 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4318}
4319#endif /* HAVE_WAIT4 */
4320
Guido van Rossumb6775db1994-08-01 11:34:53 +00004321#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004322PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004323"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004324Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004325
Barry Warsaw53699e91996-12-10 23:23:01 +00004326static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004327posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004328{
Christian Heimes292d3512008-02-03 16:51:08 +00004329 pid_t pid;
4330 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004331 WAIT_TYPE status;
4332 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004333
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004334 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004335 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004336 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004337 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004338 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004339 if (pid == -1)
4340 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004341
4342 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004343}
4344
Tim Petersab034fa2002-02-01 11:27:43 +00004345#elif defined(HAVE_CWAIT)
4346
4347/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004348PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004349"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004350"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004351
4352static PyObject *
4353posix_waitpid(PyObject *self, PyObject *args)
4354{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004355 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004356 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004357
4358 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4359 return NULL;
4360 Py_BEGIN_ALLOW_THREADS
4361 pid = _cwait(&status, pid, options);
4362 Py_END_ALLOW_THREADS
4363 if (pid == -1)
4364 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004365
4366 /* shift the status left a byte so this is more like the POSIX waitpid */
4367 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004368}
4369#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004370
Guido van Rossumad0ee831995-03-01 10:34:45 +00004371#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004372PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004373"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004374Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004375
Barry Warsaw53699e91996-12-10 23:23:01 +00004376static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004377posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004378{
Christian Heimes292d3512008-02-03 16:51:08 +00004379 pid_t pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004380 WAIT_TYPE status;
4381 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004382
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004383 Py_BEGIN_ALLOW_THREADS
4384 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004385 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004386 if (pid == -1)
4387 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004388
4389 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004390}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004391#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004392
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004393
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004394PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004395"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004396Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004397
Barry Warsaw53699e91996-12-10 23:23:01 +00004398static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004399posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004400{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004401#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004402 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004403#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004404#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00004405 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004406#else
4407 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4408#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004409#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004410}
4411
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004412
Guido van Rossumb6775db1994-08-01 11:34:53 +00004413#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004414PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004415"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004416Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004417
Barry Warsaw53699e91996-12-10 23:23:01 +00004418static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004419posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004420{
Thomas Wouters89f507f2006-12-13 04:49:30 +00004421 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004422 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004423 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004424 int n;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004425 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004426
4427 if (!PyArg_ParseTuple(args, "et:readlink",
4428 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004429 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004430 v = PySequence_GetItem(args, 0);
Neal Norwitzcda5c062007-08-12 17:09:36 +00004431 if (v == NULL) {
4432 PyMem_Free(path);
4433 return NULL;
4434 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004435
4436 if (PyUnicode_Check(v)) {
4437 arg_is_unicode = 1;
4438 }
4439 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004440
Barry Warsaw53699e91996-12-10 23:23:01 +00004441 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004442 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004443 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004444 if (n < 0)
Neal Norwitzfca70052007-08-12 16:56:02 +00004445 return posix_error_with_allocated_filename(path);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004446
Neal Norwitzfca70052007-08-12 16:56:02 +00004447 PyMem_Free(path);
Christian Heimes72b710a2008-05-26 13:28:38 +00004448 v = PyBytes_FromStringAndSize(buf, n);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004449 if (arg_is_unicode) {
4450 PyObject *w;
4451
4452 w = PyUnicode_FromEncodedObject(v,
4453 Py_FileSystemDefaultEncoding,
4454 "strict");
4455 if (w != NULL) {
4456 Py_DECREF(v);
4457 v = w;
4458 }
4459 else {
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004460 v = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004461 }
4462 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004463 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004464}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004465#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004466
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004467
Guido van Rossumb6775db1994-08-01 11:34:53 +00004468#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004469PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004470"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004471Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004472
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004473static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004474posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004475{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004476 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004477}
4478#endif /* HAVE_SYMLINK */
4479
4480
4481#ifdef HAVE_TIMES
4482#ifndef HZ
4483#define HZ 60 /* Universal constant :-) */
4484#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004485
Guido van Rossumd48f2521997-12-05 22:19:34 +00004486#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4487static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004488system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004489{
4490 ULONG value = 0;
4491
4492 Py_BEGIN_ALLOW_THREADS
4493 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4494 Py_END_ALLOW_THREADS
4495
4496 return value;
4497}
4498
4499static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004500posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004501{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004502 /* Currently Only Uptime is Provided -- Others Later */
4503 return Py_BuildValue("ddddd",
4504 (double)0 /* t.tms_utime / HZ */,
4505 (double)0 /* t.tms_stime / HZ */,
4506 (double)0 /* t.tms_cutime / HZ */,
4507 (double)0 /* t.tms_cstime / HZ */,
4508 (double)system_uptime() / 1000);
4509}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004510#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004511static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004512posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004513{
4514 struct tms t;
4515 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004516 errno = 0;
4517 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004518 if (c == (clock_t) -1)
4519 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004520 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004521 (double)t.tms_utime / HZ,
4522 (double)t.tms_stime / HZ,
4523 (double)t.tms_cutime / HZ,
4524 (double)t.tms_cstime / HZ,
4525 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004526}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004527#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004528#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004529
4530
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004531#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004532#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004533static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004534posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004535{
4536 FILETIME create, exit, kernel, user;
4537 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004538 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004539 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4540 /* The fields of a FILETIME structure are the hi and lo part
4541 of a 64-bit value expressed in 100 nanosecond units.
4542 1e7 is one second in such units; 1e-7 the inverse.
4543 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4544 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004545 return Py_BuildValue(
4546 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004547 (double)(user.dwHighDateTime*429.4967296 +
4548 user.dwLowDateTime*1e-7),
Christian Heimes68f5fbe2008-02-14 08:27:37 +00004549 (double)(kernel.dwHighDateTime*429.4967296 +
4550 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004551 (double)0,
4552 (double)0,
4553 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004554}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004555#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004556
4557#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004558PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004559"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004560Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004561#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004562
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004563
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004564#ifdef HAVE_GETSID
4565PyDoc_STRVAR(posix_getsid__doc__,
4566"getsid(pid) -> sid\n\n\
4567Call the system call getsid().");
4568
4569static PyObject *
4570posix_getsid(PyObject *self, PyObject *args)
4571{
Christian Heimes292d3512008-02-03 16:51:08 +00004572 pid_t pid;
4573 int sid;
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004574 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
4575 return NULL;
4576 sid = getsid(pid);
4577 if (sid < 0)
4578 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004579 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004580}
4581#endif /* HAVE_GETSID */
4582
4583
Guido van Rossumb6775db1994-08-01 11:34:53 +00004584#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004585PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004586"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004587Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004588
Barry Warsaw53699e91996-12-10 23:23:01 +00004589static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004590posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004591{
Guido van Rossum687dd131993-05-17 08:34:16 +00004592 if (setsid() < 0)
4593 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004594 Py_INCREF(Py_None);
4595 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004596}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004597#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004598
Guido van Rossumb6775db1994-08-01 11:34:53 +00004599#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004600PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004601"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004602Call the system call setpgid().");
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_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004606{
Christian Heimes292d3512008-02-03 16:51:08 +00004607 pid_t pid;
4608 int pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004609 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004610 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004611 if (setpgid(pid, pgrp) < 0)
4612 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004613 Py_INCREF(Py_None);
4614 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004615}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004616#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004617
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004618
Guido van Rossumb6775db1994-08-01 11:34:53 +00004619#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004620PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004621"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004622Return the process group associated with the terminal given by a fd.");
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_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004626{
Christian Heimes15ebc882008-02-04 18:48:49 +00004627 int fd;
4628 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004629 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004630 return NULL;
4631 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004632 if (pgid < 0)
4633 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004634 return PyLong_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004635}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004636#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004637
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004638
Guido van Rossumb6775db1994-08-01 11:34:53 +00004639#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004640PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004641"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004642Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004643
Barry Warsaw53699e91996-12-10 23:23:01 +00004644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004645posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004646{
4647 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004648 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004649 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004650 if (tcsetpgrp(fd, pgid) < 0)
4651 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004652 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004653 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004654}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004655#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004656
Guido van Rossum687dd131993-05-17 08:34:16 +00004657/* Functions acting on file descriptors */
4658
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004659PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004660"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004661Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004662
Barry Warsaw53699e91996-12-10 23:23:01 +00004663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004664posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004665{
Mark Hammondef8b6542001-05-13 08:04:26 +00004666 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004667 int flag;
4668 int mode = 0777;
4669 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004670
4671#ifdef MS_WINDOWS
4672 if (unicode_file_names()) {
4673 PyUnicodeObject *po;
4674 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4675 Py_BEGIN_ALLOW_THREADS
4676 /* PyUnicode_AS_UNICODE OK without thread
4677 lock as it is a simple dereference. */
4678 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4679 Py_END_ALLOW_THREADS
4680 if (fd < 0)
4681 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004682 return PyLong_FromLong((long)fd);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004683 }
4684 /* Drop the argument parsing error as narrow strings
4685 are also valid. */
4686 PyErr_Clear();
4687 }
4688#endif
4689
Tim Peters5aa91602002-01-30 05:46:57 +00004690 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004691 Py_FileSystemDefaultEncoding, &file,
4692 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004693 return NULL;
4694
Barry Warsaw53699e91996-12-10 23:23:01 +00004695 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004696 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004697 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004698 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004699 return posix_error_with_allocated_filename(file);
4700 PyMem_Free(file);
Christian Heimes217cfd12007-12-02 14:31:20 +00004701 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004702}
4703
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004704
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004705PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004706"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004707Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004708
Barry Warsaw53699e91996-12-10 23:23:01 +00004709static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004710posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004711{
4712 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004713 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004714 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004715 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004716 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004717 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004718 if (res < 0)
4719 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004720 Py_INCREF(Py_None);
4721 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004722}
4723
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004724
Christian Heimesfdab48e2008-01-20 09:06:41 +00004725PyDoc_STRVAR(posix_closerange__doc__,
4726"closerange(fd_low, fd_high)\n\n\
4727Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
4728
4729static PyObject *
4730posix_closerange(PyObject *self, PyObject *args)
4731{
4732 int fd_from, fd_to, i;
4733 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
4734 return NULL;
4735 Py_BEGIN_ALLOW_THREADS
4736 for (i = fd_from; i < fd_to; i++)
4737 close(i);
4738 Py_END_ALLOW_THREADS
4739 Py_RETURN_NONE;
4740}
4741
4742
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004743PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004744"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004745Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004746
Barry Warsaw53699e91996-12-10 23:23:01 +00004747static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004748posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004749{
4750 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004751 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004752 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004753 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004754 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004755 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004756 if (fd < 0)
4757 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004758 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004759}
4760
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004761
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004762PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00004763"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004764Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004765
Barry Warsaw53699e91996-12-10 23:23:01 +00004766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004767posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004768{
4769 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004770 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004771 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004772 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004773 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004774 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004775 if (res < 0)
4776 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004777 Py_INCREF(Py_None);
4778 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004779}
4780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004781
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004782PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004783"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004784Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004785
Barry Warsaw53699e91996-12-10 23:23:01 +00004786static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004787posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004788{
4789 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004790#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00004791 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004792#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004793 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004794#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004795 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004796 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004797 return NULL;
4798#ifdef SEEK_SET
4799 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4800 switch (how) {
4801 case 0: how = SEEK_SET; break;
4802 case 1: how = SEEK_CUR; break;
4803 case 2: how = SEEK_END; break;
4804 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004805#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004806
4807#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00004808 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004809#else
4810 pos = PyLong_Check(posobj) ?
Christian Heimes217cfd12007-12-02 14:31:20 +00004811 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004812#endif
4813 if (PyErr_Occurred())
4814 return NULL;
4815
Barry Warsaw53699e91996-12-10 23:23:01 +00004816 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004817#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004818 res = _lseeki64(fd, pos, how);
4819#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004820 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004821#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004822 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004823 if (res < 0)
4824 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004825
4826#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00004827 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004828#else
4829 return PyLong_FromLongLong(res);
4830#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004831}
4832
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004833
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004834PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004835"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004836Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004837
Barry Warsaw53699e91996-12-10 23:23:01 +00004838static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004839posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004840{
Guido van Rossum572dbf82007-04-27 23:53:51 +00004841 int fd, size;
4842 Py_ssize_t n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004843 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004844 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004845 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00004846 if (size < 0) {
4847 errno = EINVAL;
4848 return posix_error();
4849 }
Christian Heimes72b710a2008-05-26 13:28:38 +00004850 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004851 if (buffer == NULL)
4852 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004853 Py_BEGIN_ALLOW_THREADS
Christian Heimes72b710a2008-05-26 13:28:38 +00004854 n = read(fd, PyBytes_AS_STRING(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004855 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004856 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004857 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004858 return posix_error();
4859 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004860 if (n != size)
Christian Heimes72b710a2008-05-26 13:28:38 +00004861 _PyBytes_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004862 return buffer;
4863}
4864
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004865
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004866PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004867"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004868Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004869
Barry Warsaw53699e91996-12-10 23:23:01 +00004870static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004871posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004872{
Martin v. Löwis423be952008-08-13 15:53:07 +00004873 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004874 int fd;
4875 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004876
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +00004877 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00004878 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004879 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis423be952008-08-13 15:53:07 +00004880 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00004881 Py_END_ALLOW_THREADS
Martin v. Löwis423be952008-08-13 15:53:07 +00004882 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00004883 if (size < 0)
4884 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004885 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004886}
4887
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004888
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004889PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004890"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004891Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004892
Barry Warsaw53699e91996-12-10 23:23:01 +00004893static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004894posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004895{
4896 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004897 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004898 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004899 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004900 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00004901#ifdef __VMS
4902 /* on OpenVMS we must ensure that all bytes are written to the file */
4903 fsync(fd);
4904#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004905 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004906 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004907 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00004908 if (res != 0) {
4909#ifdef MS_WINDOWS
4910 return win32_error("fstat", NULL);
4911#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004912 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00004913#endif
4914 }
Tim Peters5aa91602002-01-30 05:46:57 +00004915
Martin v. Löwis14694662006-02-03 12:54:16 +00004916 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004917}
4918
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004919PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004920"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004921Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004922connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004923
4924static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004925posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004926{
4927 int fd;
4928 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4929 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004930 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004931}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004932
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004933#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004934PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004935"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004936Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004937
Barry Warsaw53699e91996-12-10 23:23:01 +00004938static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004939posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00004940{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004941#if defined(PYOS_OS2)
4942 HFILE read, write;
4943 APIRET rc;
4944
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004945 Py_BEGIN_ALLOW_THREADS
4946 rc = DosCreatePipe( &read, &write, 4096);
4947 Py_END_ALLOW_THREADS
4948 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004949 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004950
4951 return Py_BuildValue("(ii)", read, write);
4952#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004953#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00004954 int fds[2];
4955 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00004956 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004957 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004958 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004959 if (res != 0)
4960 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004961 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004962#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00004963 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004964 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004965 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00004966 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004967 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004968 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004969 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004970 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004971 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4972 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004973 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004974#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004975#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004976}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004977#endif /* HAVE_PIPE */
4978
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004979
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004980#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004981PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00004982"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004983Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004984
Barry Warsaw53699e91996-12-10 23:23:01 +00004985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004986posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004987{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004988 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004989 int mode = 0666;
4990 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004991 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004992 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004993 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004994 res = mkfifo(filename, mode);
4995 Py_END_ALLOW_THREADS
4996 if (res < 0)
4997 return posix_error();
4998 Py_INCREF(Py_None);
4999 return Py_None;
5000}
5001#endif
5002
5003
Neal Norwitz11690112002-07-30 01:08:28 +00005004#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005005PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005006"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005007Create a filesystem node (file, device special file or named pipe)\n\
5008named filename. mode specifies both the permissions to use and the\n\
5009type of node to be created, being combined (bitwise OR) with one of\n\
5010S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005011device defines the newly created device special file (probably using\n\
5012os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005013
5014
5015static PyObject *
5016posix_mknod(PyObject *self, PyObject *args)
5017{
5018 char *filename;
5019 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005020 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005021 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005022 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005023 return NULL;
5024 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005025 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005026 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005027 if (res < 0)
5028 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005029 Py_INCREF(Py_None);
5030 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005031}
5032#endif
5033
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005034#ifdef HAVE_DEVICE_MACROS
5035PyDoc_STRVAR(posix_major__doc__,
5036"major(device) -> major number\n\
5037Extracts a device major number from a raw device number.");
5038
5039static PyObject *
5040posix_major(PyObject *self, PyObject *args)
5041{
5042 int device;
5043 if (!PyArg_ParseTuple(args, "i:major", &device))
5044 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005045 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005046}
5047
5048PyDoc_STRVAR(posix_minor__doc__,
5049"minor(device) -> minor number\n\
5050Extracts a device minor number from a raw device number.");
5051
5052static PyObject *
5053posix_minor(PyObject *self, PyObject *args)
5054{
5055 int device;
5056 if (!PyArg_ParseTuple(args, "i:minor", &device))
5057 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005058 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005059}
5060
5061PyDoc_STRVAR(posix_makedev__doc__,
5062"makedev(major, minor) -> device number\n\
5063Composes a raw device number from the major and minor device numbers.");
5064
5065static PyObject *
5066posix_makedev(PyObject *self, PyObject *args)
5067{
5068 int major, minor;
5069 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5070 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005071 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005072}
5073#endif /* device macros */
5074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005075
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005076#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005077PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005078"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005079Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005080
Barry Warsaw53699e91996-12-10 23:23:01 +00005081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005082posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005083{
5084 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005085 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005086 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005087 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005088
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005089 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005090 return NULL;
5091
5092#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005093 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005094#else
5095 length = PyLong_Check(lenobj) ?
Christian Heimes217cfd12007-12-02 14:31:20 +00005096 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005097#endif
5098 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005099 return NULL;
5100
Barry Warsaw53699e91996-12-10 23:23:01 +00005101 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005102 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005103 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005104 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005105 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005106 return NULL;
5107 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005108 Py_INCREF(Py_None);
5109 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005110}
5111#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005112
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005113#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005114PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005115"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005116Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005117
Fred Drake762e2061999-08-26 17:23:54 +00005118/* Save putenv() parameters as values here, so we can collect them when they
5119 * get re-set with another call for the same key. */
5120static PyObject *posix_putenv_garbage;
5121
Tim Peters5aa91602002-01-30 05:46:57 +00005122static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005123posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005124{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005125#ifdef MS_WINDOWS
5126 wchar_t *s1, *s2;
5127 wchar_t *newenv;
5128#else
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005129 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005130 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005131#endif
Fred Drake762e2061999-08-26 17:23:54 +00005132 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005133 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005134
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005135 if (!PyArg_ParseTuple(args,
5136#ifdef MS_WINDOWS
5137 "uu:putenv",
5138#else
5139 "ss:putenv",
5140#endif
5141 &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005142 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005143
5144#if defined(PYOS_OS2)
5145 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5146 APIRET rc;
5147
Guido van Rossumd48f2521997-12-05 22:19:34 +00005148 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5149 if (rc != NO_ERROR)
5150 return os2_error(rc);
5151
5152 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5153 APIRET rc;
5154
Guido van Rossumd48f2521997-12-05 22:19:34 +00005155 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5156 if (rc != NO_ERROR)
5157 return os2_error(rc);
5158 } else {
5159#endif
Fred Drake762e2061999-08-26 17:23:54 +00005160 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005161 /* len includes space for a trailing \0; the size arg to
Christian Heimes72b710a2008-05-26 13:28:38 +00005162 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005163#ifdef MS_WINDOWS
5164 len = wcslen(s1) + wcslen(s2) + 2;
5165 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
5166#else
5167 len = strlen(s1) + strlen(s2) + 2;
Christian Heimes72b710a2008-05-26 13:28:38 +00005168 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005169#endif
Fred Drake762e2061999-08-26 17:23:54 +00005170 if (newstr == NULL)
5171 return PyErr_NoMemory();
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005172#ifdef MS_WINDOWS
5173 newenv = PyUnicode_AsUnicode(newstr);
5174 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5175 if (_wputenv(newenv)) {
5176 Py_DECREF(newstr);
5177 posix_error();
5178 return NULL;
5179 }
5180#else
Christian Heimes72b710a2008-05-26 13:28:38 +00005181 newenv = PyBytes_AS_STRING(newstr);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005182 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5183 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005184 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005185 posix_error();
5186 return NULL;
5187 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005188#endif
Fred Drake762e2061999-08-26 17:23:54 +00005189 /* Install the first arg and newstr in posix_putenv_garbage;
5190 * this will cause previous value to be collected. This has to
5191 * happen after the real putenv() call because the old value
5192 * was still accessible until then. */
5193 if (PyDict_SetItem(posix_putenv_garbage,
5194 PyTuple_GET_ITEM(args, 0), newstr)) {
5195 /* really not much we can do; just leak */
5196 PyErr_Clear();
5197 }
5198 else {
5199 Py_DECREF(newstr);
5200 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005201
5202#if defined(PYOS_OS2)
5203 }
5204#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005205 Py_INCREF(Py_None);
5206 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005207}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005208#endif /* putenv */
5209
Guido van Rossumc524d952001-10-19 01:31:59 +00005210#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005211PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005212"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005213Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005214
5215static PyObject *
5216posix_unsetenv(PyObject *self, PyObject *args)
5217{
5218 char *s1;
5219
5220 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5221 return NULL;
5222
5223 unsetenv(s1);
5224
5225 /* Remove the key from posix_putenv_garbage;
5226 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005227 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005228 * old value was still accessible until then.
5229 */
5230 if (PyDict_DelItem(posix_putenv_garbage,
5231 PyTuple_GET_ITEM(args, 0))) {
5232 /* really not much we can do; just leak */
5233 PyErr_Clear();
5234 }
5235
5236 Py_INCREF(Py_None);
5237 return Py_None;
5238}
5239#endif /* unsetenv */
5240
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005241PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005242"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005243Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005244
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005245static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005246posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005247{
5248 int code;
5249 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005250 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005251 return NULL;
5252 message = strerror(code);
5253 if (message == NULL) {
5254 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005255 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005256 return NULL;
5257 }
Neal Norwitz93c56822007-08-26 07:10:06 +00005258 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005259}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005260
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005261
Guido van Rossumc9641791998-08-04 15:26:23 +00005262#ifdef HAVE_SYS_WAIT_H
5263
Fred Drake106c1a02002-04-23 15:58:02 +00005264#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005265PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005266"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005267Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005268
5269static PyObject *
5270posix_WCOREDUMP(PyObject *self, PyObject *args)
5271{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005272 WAIT_TYPE status;
5273 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005274
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005275 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005276 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005277
5278 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005279}
5280#endif /* WCOREDUMP */
5281
5282#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005283PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005284"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005285Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005286job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005287
5288static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005289posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005290{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005291 WAIT_TYPE status;
5292 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005293
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005294 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005295 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005296
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005297 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005298}
5299#endif /* WIFCONTINUED */
5300
Guido van Rossumc9641791998-08-04 15:26:23 +00005301#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005302PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005303"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005304Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005305
5306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005307posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005308{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005309 WAIT_TYPE status;
5310 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005311
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005312 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005313 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005314
Fred Drake106c1a02002-04-23 15:58:02 +00005315 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005316}
5317#endif /* WIFSTOPPED */
5318
5319#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005320PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005321"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005322Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005323
5324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005325posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005326{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005327 WAIT_TYPE status;
5328 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005329
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005330 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005331 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005332
Fred Drake106c1a02002-04-23 15:58:02 +00005333 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005334}
5335#endif /* WIFSIGNALED */
5336
5337#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005338PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005339"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005340Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005341system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005342
5343static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005344posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005345{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005346 WAIT_TYPE status;
5347 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005348
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005349 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005350 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005351
Fred Drake106c1a02002-04-23 15:58:02 +00005352 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005353}
5354#endif /* WIFEXITED */
5355
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005356#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005357PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005358"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005359Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005360
5361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005362posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005363{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005364 WAIT_TYPE status;
5365 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005366
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005367 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005368 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005369
Guido van Rossumc9641791998-08-04 15:26:23 +00005370 return Py_BuildValue("i", WEXITSTATUS(status));
5371}
5372#endif /* WEXITSTATUS */
5373
5374#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005375PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005376"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005377Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005378value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005379
5380static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005381posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005382{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005383 WAIT_TYPE status;
5384 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005385
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005386 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005387 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005388
Guido van Rossumc9641791998-08-04 15:26:23 +00005389 return Py_BuildValue("i", WTERMSIG(status));
5390}
5391#endif /* WTERMSIG */
5392
5393#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005394PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005395"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005396Return the signal that stopped the process that provided\n\
5397the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005398
5399static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005400posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005401{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005402 WAIT_TYPE status;
5403 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005404
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005405 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005406 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005407
Guido van Rossumc9641791998-08-04 15:26:23 +00005408 return Py_BuildValue("i", WSTOPSIG(status));
5409}
5410#endif /* WSTOPSIG */
5411
5412#endif /* HAVE_SYS_WAIT_H */
5413
5414
Thomas Wouters477c8d52006-05-27 19:21:47 +00005415#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005416#ifdef _SCO_DS
5417/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5418 needed definitions in sys/statvfs.h */
5419#define _SVID3
5420#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005421#include <sys/statvfs.h>
5422
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005423static PyObject*
5424_pystatvfs_fromstructstatvfs(struct statvfs st) {
5425 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5426 if (v == NULL)
5427 return NULL;
5428
5429#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005430 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5431 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5432 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
5433 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
5434 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
5435 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
5436 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
5437 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
5438 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5439 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005440#else
Christian Heimes217cfd12007-12-02 14:31:20 +00005441 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5442 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005443 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005444 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005445 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005446 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005447 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005448 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005449 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005450 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005451 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005452 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005453 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005454 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Christian Heimes217cfd12007-12-02 14:31:20 +00005455 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5456 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005457#endif
5458
5459 return v;
5460}
5461
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005462PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005463"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005464Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005465
5466static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005467posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005468{
5469 int fd, res;
5470 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005471
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005472 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005473 return NULL;
5474 Py_BEGIN_ALLOW_THREADS
5475 res = fstatvfs(fd, &st);
5476 Py_END_ALLOW_THREADS
5477 if (res != 0)
5478 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005479
5480 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005481}
Thomas Wouters477c8d52006-05-27 19:21:47 +00005482#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005483
5484
Thomas Wouters477c8d52006-05-27 19:21:47 +00005485#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005486#include <sys/statvfs.h>
5487
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005488PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005489"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005490Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005491
5492static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005493posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005494{
5495 char *path;
5496 int res;
5497 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005498 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005499 return NULL;
5500 Py_BEGIN_ALLOW_THREADS
5501 res = statvfs(path, &st);
5502 Py_END_ALLOW_THREADS
5503 if (res != 0)
5504 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005505
5506 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005507}
5508#endif /* HAVE_STATVFS */
5509
Fred Drakec9680921999-12-13 16:37:25 +00005510/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5511 * It maps strings representing configuration variable names to
5512 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005513 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005514 * rarely-used constants. There are three separate tables that use
5515 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005516 *
5517 * This code is always included, even if none of the interfaces that
5518 * need it are included. The #if hackery needed to avoid it would be
5519 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005520 */
5521struct constdef {
5522 char *name;
5523 long value;
5524};
5525
Fred Drake12c6e2d1999-12-14 21:25:03 +00005526static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005527conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005528 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005529{
Christian Heimes217cfd12007-12-02 14:31:20 +00005530 if (PyLong_Check(arg)) {
5531 *valuep = PyLong_AS_LONG(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005532 return 1;
5533 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00005534 else {
Fred Drake12c6e2d1999-12-14 21:25:03 +00005535 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005536 size_t lo = 0;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005537 size_t mid;
Fred Drake699f3522000-06-29 21:12:41 +00005538 size_t hi = tablesize;
5539 int cmp;
Guido van Rossumbce56a62007-05-10 18:04:33 +00005540 const char *confname;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005541 if (!PyUnicode_Check(arg)) {
Guido van Rossumbce56a62007-05-10 18:04:33 +00005542 PyErr_SetString(PyExc_TypeError,
5543 "configuration names must be strings or integers");
5544 return 0;
5545 }
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00005546 confname = _PyUnicode_AsString(arg);
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005547 if (confname == NULL)
5548 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005549 while (lo < hi) {
5550 mid = (lo + hi) / 2;
5551 cmp = strcmp(confname, table[mid].name);
5552 if (cmp < 0)
5553 hi = mid;
5554 else if (cmp > 0)
5555 lo = mid + 1;
5556 else {
5557 *valuep = table[mid].value;
5558 return 1;
5559 }
5560 }
5561 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Guido van Rossumbce56a62007-05-10 18:04:33 +00005562 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005563 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005564}
5565
5566
5567#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5568static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005569#ifdef _PC_ABI_AIO_XFER_MAX
5570 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5571#endif
5572#ifdef _PC_ABI_ASYNC_IO
5573 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5574#endif
Fred Drakec9680921999-12-13 16:37:25 +00005575#ifdef _PC_ASYNC_IO
5576 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5577#endif
5578#ifdef _PC_CHOWN_RESTRICTED
5579 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5580#endif
5581#ifdef _PC_FILESIZEBITS
5582 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5583#endif
5584#ifdef _PC_LAST
5585 {"PC_LAST", _PC_LAST},
5586#endif
5587#ifdef _PC_LINK_MAX
5588 {"PC_LINK_MAX", _PC_LINK_MAX},
5589#endif
5590#ifdef _PC_MAX_CANON
5591 {"PC_MAX_CANON", _PC_MAX_CANON},
5592#endif
5593#ifdef _PC_MAX_INPUT
5594 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5595#endif
5596#ifdef _PC_NAME_MAX
5597 {"PC_NAME_MAX", _PC_NAME_MAX},
5598#endif
5599#ifdef _PC_NO_TRUNC
5600 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5601#endif
5602#ifdef _PC_PATH_MAX
5603 {"PC_PATH_MAX", _PC_PATH_MAX},
5604#endif
5605#ifdef _PC_PIPE_BUF
5606 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5607#endif
5608#ifdef _PC_PRIO_IO
5609 {"PC_PRIO_IO", _PC_PRIO_IO},
5610#endif
5611#ifdef _PC_SOCK_MAXBUF
5612 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5613#endif
5614#ifdef _PC_SYNC_IO
5615 {"PC_SYNC_IO", _PC_SYNC_IO},
5616#endif
5617#ifdef _PC_VDISABLE
5618 {"PC_VDISABLE", _PC_VDISABLE},
5619#endif
5620};
5621
Fred Drakec9680921999-12-13 16:37:25 +00005622static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005623conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005624{
5625 return conv_confname(arg, valuep, posix_constants_pathconf,
5626 sizeof(posix_constants_pathconf)
5627 / sizeof(struct constdef));
5628}
5629#endif
5630
5631#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005632PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005633"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005634Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005635If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005636
5637static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005638posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005639{
5640 PyObject *result = NULL;
5641 int name, fd;
5642
Fred Drake12c6e2d1999-12-14 21:25:03 +00005643 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5644 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005645 long limit;
5646
5647 errno = 0;
5648 limit = fpathconf(fd, name);
5649 if (limit == -1 && errno != 0)
5650 posix_error();
5651 else
Christian Heimes217cfd12007-12-02 14:31:20 +00005652 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005653 }
5654 return result;
5655}
5656#endif
5657
5658
5659#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005660PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005661"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005662Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005663If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005664
5665static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005666posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005667{
5668 PyObject *result = NULL;
5669 int name;
5670 char *path;
5671
5672 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5673 conv_path_confname, &name)) {
5674 long limit;
5675
5676 errno = 0;
5677 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005678 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005679 if (errno == EINVAL)
5680 /* could be a path or name problem */
5681 posix_error();
5682 else
5683 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005684 }
Fred Drakec9680921999-12-13 16:37:25 +00005685 else
Christian Heimes217cfd12007-12-02 14:31:20 +00005686 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005687 }
5688 return result;
5689}
5690#endif
5691
5692#ifdef HAVE_CONFSTR
5693static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005694#ifdef _CS_ARCHITECTURE
5695 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5696#endif
5697#ifdef _CS_HOSTNAME
5698 {"CS_HOSTNAME", _CS_HOSTNAME},
5699#endif
5700#ifdef _CS_HW_PROVIDER
5701 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5702#endif
5703#ifdef _CS_HW_SERIAL
5704 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5705#endif
5706#ifdef _CS_INITTAB_NAME
5707 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5708#endif
Fred Drakec9680921999-12-13 16:37:25 +00005709#ifdef _CS_LFS64_CFLAGS
5710 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5711#endif
5712#ifdef _CS_LFS64_LDFLAGS
5713 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5714#endif
5715#ifdef _CS_LFS64_LIBS
5716 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5717#endif
5718#ifdef _CS_LFS64_LINTFLAGS
5719 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5720#endif
5721#ifdef _CS_LFS_CFLAGS
5722 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5723#endif
5724#ifdef _CS_LFS_LDFLAGS
5725 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5726#endif
5727#ifdef _CS_LFS_LIBS
5728 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5729#endif
5730#ifdef _CS_LFS_LINTFLAGS
5731 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5732#endif
Fred Draked86ed291999-12-15 15:34:33 +00005733#ifdef _CS_MACHINE
5734 {"CS_MACHINE", _CS_MACHINE},
5735#endif
Fred Drakec9680921999-12-13 16:37:25 +00005736#ifdef _CS_PATH
5737 {"CS_PATH", _CS_PATH},
5738#endif
Fred Draked86ed291999-12-15 15:34:33 +00005739#ifdef _CS_RELEASE
5740 {"CS_RELEASE", _CS_RELEASE},
5741#endif
5742#ifdef _CS_SRPC_DOMAIN
5743 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5744#endif
5745#ifdef _CS_SYSNAME
5746 {"CS_SYSNAME", _CS_SYSNAME},
5747#endif
5748#ifdef _CS_VERSION
5749 {"CS_VERSION", _CS_VERSION},
5750#endif
Fred Drakec9680921999-12-13 16:37:25 +00005751#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5752 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5753#endif
5754#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5755 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5756#endif
5757#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5758 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5759#endif
5760#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5761 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5762#endif
5763#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5764 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5765#endif
5766#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5767 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5768#endif
5769#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5770 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5771#endif
5772#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5773 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5774#endif
5775#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5776 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5777#endif
5778#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5779 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5780#endif
5781#ifdef _CS_XBS5_LP64_OFF64_LIBS
5782 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5783#endif
5784#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5785 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5786#endif
5787#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5788 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5789#endif
5790#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5791 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5792#endif
5793#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5794 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5795#endif
5796#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5797 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5798#endif
Fred Draked86ed291999-12-15 15:34:33 +00005799#ifdef _MIPS_CS_AVAIL_PROCESSORS
5800 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5801#endif
5802#ifdef _MIPS_CS_BASE
5803 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5804#endif
5805#ifdef _MIPS_CS_HOSTID
5806 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5807#endif
5808#ifdef _MIPS_CS_HW_NAME
5809 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5810#endif
5811#ifdef _MIPS_CS_NUM_PROCESSORS
5812 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5813#endif
5814#ifdef _MIPS_CS_OSREL_MAJ
5815 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5816#endif
5817#ifdef _MIPS_CS_OSREL_MIN
5818 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5819#endif
5820#ifdef _MIPS_CS_OSREL_PATCH
5821 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5822#endif
5823#ifdef _MIPS_CS_OS_NAME
5824 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5825#endif
5826#ifdef _MIPS_CS_OS_PROVIDER
5827 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5828#endif
5829#ifdef _MIPS_CS_PROCESSORS
5830 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5831#endif
5832#ifdef _MIPS_CS_SERIAL
5833 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5834#endif
5835#ifdef _MIPS_CS_VENDOR
5836 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5837#endif
Fred Drakec9680921999-12-13 16:37:25 +00005838};
5839
5840static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005841conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005842{
5843 return conv_confname(arg, valuep, posix_constants_confstr,
5844 sizeof(posix_constants_confstr)
5845 / sizeof(struct constdef));
5846}
5847
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005848PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005849"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005850Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005851
5852static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005853posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005854{
5855 PyObject *result = NULL;
5856 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005857 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00005858
5859 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005860 int len;
Fred Drakec9680921999-12-13 16:37:25 +00005861
Fred Drakec9680921999-12-13 16:37:25 +00005862 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005863 len = confstr(name, buffer, sizeof(buffer));
5864 if (len == 0) {
5865 if (errno) {
5866 posix_error();
5867 }
5868 else {
5869 result = Py_None;
5870 Py_INCREF(Py_None);
5871 }
Fred Drakec9680921999-12-13 16:37:25 +00005872 }
5873 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005874 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00005875 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00005876 if (result != NULL)
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00005877 confstr(name, _PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00005878 }
5879 else
Neal Norwitz93c56822007-08-26 07:10:06 +00005880 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00005881 }
5882 }
5883 return result;
5884}
5885#endif
5886
5887
5888#ifdef HAVE_SYSCONF
5889static struct constdef posix_constants_sysconf[] = {
5890#ifdef _SC_2_CHAR_TERM
5891 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5892#endif
5893#ifdef _SC_2_C_BIND
5894 {"SC_2_C_BIND", _SC_2_C_BIND},
5895#endif
5896#ifdef _SC_2_C_DEV
5897 {"SC_2_C_DEV", _SC_2_C_DEV},
5898#endif
5899#ifdef _SC_2_C_VERSION
5900 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5901#endif
5902#ifdef _SC_2_FORT_DEV
5903 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5904#endif
5905#ifdef _SC_2_FORT_RUN
5906 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5907#endif
5908#ifdef _SC_2_LOCALEDEF
5909 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5910#endif
5911#ifdef _SC_2_SW_DEV
5912 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5913#endif
5914#ifdef _SC_2_UPE
5915 {"SC_2_UPE", _SC_2_UPE},
5916#endif
5917#ifdef _SC_2_VERSION
5918 {"SC_2_VERSION", _SC_2_VERSION},
5919#endif
Fred Draked86ed291999-12-15 15:34:33 +00005920#ifdef _SC_ABI_ASYNCHRONOUS_IO
5921 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5922#endif
5923#ifdef _SC_ACL
5924 {"SC_ACL", _SC_ACL},
5925#endif
Fred Drakec9680921999-12-13 16:37:25 +00005926#ifdef _SC_AIO_LISTIO_MAX
5927 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5928#endif
Fred Drakec9680921999-12-13 16:37:25 +00005929#ifdef _SC_AIO_MAX
5930 {"SC_AIO_MAX", _SC_AIO_MAX},
5931#endif
5932#ifdef _SC_AIO_PRIO_DELTA_MAX
5933 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5934#endif
5935#ifdef _SC_ARG_MAX
5936 {"SC_ARG_MAX", _SC_ARG_MAX},
5937#endif
5938#ifdef _SC_ASYNCHRONOUS_IO
5939 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5940#endif
5941#ifdef _SC_ATEXIT_MAX
5942 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5943#endif
Fred Draked86ed291999-12-15 15:34:33 +00005944#ifdef _SC_AUDIT
5945 {"SC_AUDIT", _SC_AUDIT},
5946#endif
Fred Drakec9680921999-12-13 16:37:25 +00005947#ifdef _SC_AVPHYS_PAGES
5948 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5949#endif
5950#ifdef _SC_BC_BASE_MAX
5951 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5952#endif
5953#ifdef _SC_BC_DIM_MAX
5954 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5955#endif
5956#ifdef _SC_BC_SCALE_MAX
5957 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5958#endif
5959#ifdef _SC_BC_STRING_MAX
5960 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5961#endif
Fred Draked86ed291999-12-15 15:34:33 +00005962#ifdef _SC_CAP
5963 {"SC_CAP", _SC_CAP},
5964#endif
Fred Drakec9680921999-12-13 16:37:25 +00005965#ifdef _SC_CHARCLASS_NAME_MAX
5966 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5967#endif
5968#ifdef _SC_CHAR_BIT
5969 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5970#endif
5971#ifdef _SC_CHAR_MAX
5972 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5973#endif
5974#ifdef _SC_CHAR_MIN
5975 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5976#endif
5977#ifdef _SC_CHILD_MAX
5978 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5979#endif
5980#ifdef _SC_CLK_TCK
5981 {"SC_CLK_TCK", _SC_CLK_TCK},
5982#endif
5983#ifdef _SC_COHER_BLKSZ
5984 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5985#endif
5986#ifdef _SC_COLL_WEIGHTS_MAX
5987 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5988#endif
5989#ifdef _SC_DCACHE_ASSOC
5990 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5991#endif
5992#ifdef _SC_DCACHE_BLKSZ
5993 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5994#endif
5995#ifdef _SC_DCACHE_LINESZ
5996 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5997#endif
5998#ifdef _SC_DCACHE_SZ
5999 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6000#endif
6001#ifdef _SC_DCACHE_TBLKSZ
6002 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6003#endif
6004#ifdef _SC_DELAYTIMER_MAX
6005 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6006#endif
6007#ifdef _SC_EQUIV_CLASS_MAX
6008 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6009#endif
6010#ifdef _SC_EXPR_NEST_MAX
6011 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6012#endif
6013#ifdef _SC_FSYNC
6014 {"SC_FSYNC", _SC_FSYNC},
6015#endif
6016#ifdef _SC_GETGR_R_SIZE_MAX
6017 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6018#endif
6019#ifdef _SC_GETPW_R_SIZE_MAX
6020 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6021#endif
6022#ifdef _SC_ICACHE_ASSOC
6023 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6024#endif
6025#ifdef _SC_ICACHE_BLKSZ
6026 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6027#endif
6028#ifdef _SC_ICACHE_LINESZ
6029 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6030#endif
6031#ifdef _SC_ICACHE_SZ
6032 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6033#endif
Fred Draked86ed291999-12-15 15:34:33 +00006034#ifdef _SC_INF
6035 {"SC_INF", _SC_INF},
6036#endif
Fred Drakec9680921999-12-13 16:37:25 +00006037#ifdef _SC_INT_MAX
6038 {"SC_INT_MAX", _SC_INT_MAX},
6039#endif
6040#ifdef _SC_INT_MIN
6041 {"SC_INT_MIN", _SC_INT_MIN},
6042#endif
6043#ifdef _SC_IOV_MAX
6044 {"SC_IOV_MAX", _SC_IOV_MAX},
6045#endif
Fred Draked86ed291999-12-15 15:34:33 +00006046#ifdef _SC_IP_SECOPTS
6047 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6048#endif
Fred Drakec9680921999-12-13 16:37:25 +00006049#ifdef _SC_JOB_CONTROL
6050 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6051#endif
Fred Draked86ed291999-12-15 15:34:33 +00006052#ifdef _SC_KERN_POINTERS
6053 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6054#endif
6055#ifdef _SC_KERN_SIM
6056 {"SC_KERN_SIM", _SC_KERN_SIM},
6057#endif
Fred Drakec9680921999-12-13 16:37:25 +00006058#ifdef _SC_LINE_MAX
6059 {"SC_LINE_MAX", _SC_LINE_MAX},
6060#endif
6061#ifdef _SC_LOGIN_NAME_MAX
6062 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6063#endif
6064#ifdef _SC_LOGNAME_MAX
6065 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6066#endif
6067#ifdef _SC_LONG_BIT
6068 {"SC_LONG_BIT", _SC_LONG_BIT},
6069#endif
Fred Draked86ed291999-12-15 15:34:33 +00006070#ifdef _SC_MAC
6071 {"SC_MAC", _SC_MAC},
6072#endif
Fred Drakec9680921999-12-13 16:37:25 +00006073#ifdef _SC_MAPPED_FILES
6074 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6075#endif
6076#ifdef _SC_MAXPID
6077 {"SC_MAXPID", _SC_MAXPID},
6078#endif
6079#ifdef _SC_MB_LEN_MAX
6080 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6081#endif
6082#ifdef _SC_MEMLOCK
6083 {"SC_MEMLOCK", _SC_MEMLOCK},
6084#endif
6085#ifdef _SC_MEMLOCK_RANGE
6086 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6087#endif
6088#ifdef _SC_MEMORY_PROTECTION
6089 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6090#endif
6091#ifdef _SC_MESSAGE_PASSING
6092 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6093#endif
Fred Draked86ed291999-12-15 15:34:33 +00006094#ifdef _SC_MMAP_FIXED_ALIGNMENT
6095 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6096#endif
Fred Drakec9680921999-12-13 16:37:25 +00006097#ifdef _SC_MQ_OPEN_MAX
6098 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6099#endif
6100#ifdef _SC_MQ_PRIO_MAX
6101 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6102#endif
Fred Draked86ed291999-12-15 15:34:33 +00006103#ifdef _SC_NACLS_MAX
6104 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6105#endif
Fred Drakec9680921999-12-13 16:37:25 +00006106#ifdef _SC_NGROUPS_MAX
6107 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6108#endif
6109#ifdef _SC_NL_ARGMAX
6110 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6111#endif
6112#ifdef _SC_NL_LANGMAX
6113 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6114#endif
6115#ifdef _SC_NL_MSGMAX
6116 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6117#endif
6118#ifdef _SC_NL_NMAX
6119 {"SC_NL_NMAX", _SC_NL_NMAX},
6120#endif
6121#ifdef _SC_NL_SETMAX
6122 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6123#endif
6124#ifdef _SC_NL_TEXTMAX
6125 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6126#endif
6127#ifdef _SC_NPROCESSORS_CONF
6128 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6129#endif
6130#ifdef _SC_NPROCESSORS_ONLN
6131 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6132#endif
Fred Draked86ed291999-12-15 15:34:33 +00006133#ifdef _SC_NPROC_CONF
6134 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6135#endif
6136#ifdef _SC_NPROC_ONLN
6137 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6138#endif
Fred Drakec9680921999-12-13 16:37:25 +00006139#ifdef _SC_NZERO
6140 {"SC_NZERO", _SC_NZERO},
6141#endif
6142#ifdef _SC_OPEN_MAX
6143 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6144#endif
6145#ifdef _SC_PAGESIZE
6146 {"SC_PAGESIZE", _SC_PAGESIZE},
6147#endif
6148#ifdef _SC_PAGE_SIZE
6149 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6150#endif
6151#ifdef _SC_PASS_MAX
6152 {"SC_PASS_MAX", _SC_PASS_MAX},
6153#endif
6154#ifdef _SC_PHYS_PAGES
6155 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6156#endif
6157#ifdef _SC_PII
6158 {"SC_PII", _SC_PII},
6159#endif
6160#ifdef _SC_PII_INTERNET
6161 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6162#endif
6163#ifdef _SC_PII_INTERNET_DGRAM
6164 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6165#endif
6166#ifdef _SC_PII_INTERNET_STREAM
6167 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6168#endif
6169#ifdef _SC_PII_OSI
6170 {"SC_PII_OSI", _SC_PII_OSI},
6171#endif
6172#ifdef _SC_PII_OSI_CLTS
6173 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6174#endif
6175#ifdef _SC_PII_OSI_COTS
6176 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6177#endif
6178#ifdef _SC_PII_OSI_M
6179 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6180#endif
6181#ifdef _SC_PII_SOCKET
6182 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6183#endif
6184#ifdef _SC_PII_XTI
6185 {"SC_PII_XTI", _SC_PII_XTI},
6186#endif
6187#ifdef _SC_POLL
6188 {"SC_POLL", _SC_POLL},
6189#endif
6190#ifdef _SC_PRIORITIZED_IO
6191 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6192#endif
6193#ifdef _SC_PRIORITY_SCHEDULING
6194 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6195#endif
6196#ifdef _SC_REALTIME_SIGNALS
6197 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6198#endif
6199#ifdef _SC_RE_DUP_MAX
6200 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6201#endif
6202#ifdef _SC_RTSIG_MAX
6203 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6204#endif
6205#ifdef _SC_SAVED_IDS
6206 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6207#endif
6208#ifdef _SC_SCHAR_MAX
6209 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6210#endif
6211#ifdef _SC_SCHAR_MIN
6212 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6213#endif
6214#ifdef _SC_SELECT
6215 {"SC_SELECT", _SC_SELECT},
6216#endif
6217#ifdef _SC_SEMAPHORES
6218 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6219#endif
6220#ifdef _SC_SEM_NSEMS_MAX
6221 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6222#endif
6223#ifdef _SC_SEM_VALUE_MAX
6224 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6225#endif
6226#ifdef _SC_SHARED_MEMORY_OBJECTS
6227 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6228#endif
6229#ifdef _SC_SHRT_MAX
6230 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6231#endif
6232#ifdef _SC_SHRT_MIN
6233 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6234#endif
6235#ifdef _SC_SIGQUEUE_MAX
6236 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6237#endif
6238#ifdef _SC_SIGRT_MAX
6239 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6240#endif
6241#ifdef _SC_SIGRT_MIN
6242 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6243#endif
Fred Draked86ed291999-12-15 15:34:33 +00006244#ifdef _SC_SOFTPOWER
6245 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6246#endif
Fred Drakec9680921999-12-13 16:37:25 +00006247#ifdef _SC_SPLIT_CACHE
6248 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6249#endif
6250#ifdef _SC_SSIZE_MAX
6251 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6252#endif
6253#ifdef _SC_STACK_PROT
6254 {"SC_STACK_PROT", _SC_STACK_PROT},
6255#endif
6256#ifdef _SC_STREAM_MAX
6257 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6258#endif
6259#ifdef _SC_SYNCHRONIZED_IO
6260 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6261#endif
6262#ifdef _SC_THREADS
6263 {"SC_THREADS", _SC_THREADS},
6264#endif
6265#ifdef _SC_THREAD_ATTR_STACKADDR
6266 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6267#endif
6268#ifdef _SC_THREAD_ATTR_STACKSIZE
6269 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6270#endif
6271#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6272 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6273#endif
6274#ifdef _SC_THREAD_KEYS_MAX
6275 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6276#endif
6277#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6278 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6279#endif
6280#ifdef _SC_THREAD_PRIO_INHERIT
6281 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6282#endif
6283#ifdef _SC_THREAD_PRIO_PROTECT
6284 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6285#endif
6286#ifdef _SC_THREAD_PROCESS_SHARED
6287 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6288#endif
6289#ifdef _SC_THREAD_SAFE_FUNCTIONS
6290 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6291#endif
6292#ifdef _SC_THREAD_STACK_MIN
6293 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6294#endif
6295#ifdef _SC_THREAD_THREADS_MAX
6296 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6297#endif
6298#ifdef _SC_TIMERS
6299 {"SC_TIMERS", _SC_TIMERS},
6300#endif
6301#ifdef _SC_TIMER_MAX
6302 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6303#endif
6304#ifdef _SC_TTY_NAME_MAX
6305 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6306#endif
6307#ifdef _SC_TZNAME_MAX
6308 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6309#endif
6310#ifdef _SC_T_IOV_MAX
6311 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6312#endif
6313#ifdef _SC_UCHAR_MAX
6314 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6315#endif
6316#ifdef _SC_UINT_MAX
6317 {"SC_UINT_MAX", _SC_UINT_MAX},
6318#endif
6319#ifdef _SC_UIO_MAXIOV
6320 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6321#endif
6322#ifdef _SC_ULONG_MAX
6323 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6324#endif
6325#ifdef _SC_USHRT_MAX
6326 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6327#endif
6328#ifdef _SC_VERSION
6329 {"SC_VERSION", _SC_VERSION},
6330#endif
6331#ifdef _SC_WORD_BIT
6332 {"SC_WORD_BIT", _SC_WORD_BIT},
6333#endif
6334#ifdef _SC_XBS5_ILP32_OFF32
6335 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6336#endif
6337#ifdef _SC_XBS5_ILP32_OFFBIG
6338 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6339#endif
6340#ifdef _SC_XBS5_LP64_OFF64
6341 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6342#endif
6343#ifdef _SC_XBS5_LPBIG_OFFBIG
6344 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6345#endif
6346#ifdef _SC_XOPEN_CRYPT
6347 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6348#endif
6349#ifdef _SC_XOPEN_ENH_I18N
6350 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6351#endif
6352#ifdef _SC_XOPEN_LEGACY
6353 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6354#endif
6355#ifdef _SC_XOPEN_REALTIME
6356 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6357#endif
6358#ifdef _SC_XOPEN_REALTIME_THREADS
6359 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6360#endif
6361#ifdef _SC_XOPEN_SHM
6362 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6363#endif
6364#ifdef _SC_XOPEN_UNIX
6365 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6366#endif
6367#ifdef _SC_XOPEN_VERSION
6368 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6369#endif
6370#ifdef _SC_XOPEN_XCU_VERSION
6371 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6372#endif
6373#ifdef _SC_XOPEN_XPG2
6374 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6375#endif
6376#ifdef _SC_XOPEN_XPG3
6377 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6378#endif
6379#ifdef _SC_XOPEN_XPG4
6380 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6381#endif
6382};
6383
6384static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006385conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006386{
6387 return conv_confname(arg, valuep, posix_constants_sysconf,
6388 sizeof(posix_constants_sysconf)
6389 / sizeof(struct constdef));
6390}
6391
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006392PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006393"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006394Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006395
6396static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006397posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006398{
6399 PyObject *result = NULL;
6400 int name;
6401
6402 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6403 int value;
6404
6405 errno = 0;
6406 value = sysconf(name);
6407 if (value == -1 && errno != 0)
6408 posix_error();
6409 else
Christian Heimes217cfd12007-12-02 14:31:20 +00006410 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00006411 }
6412 return result;
6413}
6414#endif
6415
6416
Fred Drakebec628d1999-12-15 18:31:10 +00006417/* This code is used to ensure that the tables of configuration value names
6418 * are in sorted order as required by conv_confname(), and also to build the
6419 * the exported dictionaries that are used to publish information about the
6420 * names available on the host platform.
6421 *
6422 * Sorting the table at runtime ensures that the table is properly ordered
6423 * when used, even for platforms we're not able to test on. It also makes
6424 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006425 */
Fred Drakebec628d1999-12-15 18:31:10 +00006426
6427static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006428cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006429{
6430 const struct constdef *c1 =
6431 (const struct constdef *) v1;
6432 const struct constdef *c2 =
6433 (const struct constdef *) v2;
6434
6435 return strcmp(c1->name, c2->name);
6436}
6437
6438static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006439setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006440 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006441{
Fred Drakebec628d1999-12-15 18:31:10 +00006442 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006443 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006444
6445 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6446 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006447 if (d == NULL)
6448 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006449
Barry Warsaw3155db32000-04-13 15:20:40 +00006450 for (i=0; i < tablesize; ++i) {
Christian Heimes217cfd12007-12-02 14:31:20 +00006451 PyObject *o = PyLong_FromLong(table[i].value);
Barry Warsaw3155db32000-04-13 15:20:40 +00006452 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6453 Py_XDECREF(o);
6454 Py_DECREF(d);
6455 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006456 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006457 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006458 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006459 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006460}
6461
Fred Drakebec628d1999-12-15 18:31:10 +00006462/* Return -1 on failure, 0 on success. */
6463static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006464setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006465{
6466#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006467 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006468 sizeof(posix_constants_pathconf)
6469 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006470 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006471 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006472#endif
6473#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006474 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006475 sizeof(posix_constants_confstr)
6476 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006477 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006478 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006479#endif
6480#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006481 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006482 sizeof(posix_constants_sysconf)
6483 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006484 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006485 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006486#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006487 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006488}
Fred Draked86ed291999-12-15 15:34:33 +00006489
6490
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006491PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006492"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006493Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006494in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006495
6496static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006497posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006498{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006499 abort();
6500 /*NOTREACHED*/
6501 Py_FatalError("abort() called from Python code didn't abort!");
6502 return NULL;
6503}
Fred Drakebec628d1999-12-15 18:31:10 +00006504
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006505#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006506PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00006507"startfile(filepath [, operation]) - Start a file with its associated\n\
6508application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006509\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00006510When \"operation\" is not specified or \"open\", this acts like\n\
6511double-clicking the file in Explorer, or giving the file name as an\n\
6512argument to the DOS \"start\" command: the file is opened with whatever\n\
6513application (if any) its extension is associated.\n\
6514When another \"operation\" is given, it specifies what should be done with\n\
6515the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006516\n\
6517startfile returns as soon as the associated application is launched.\n\
6518There is no option to wait for the application to close, and no way\n\
6519to retrieve the application's exit status.\n\
6520\n\
6521The filepath is relative to the current directory. If you want to use\n\
6522an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006523the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006524
6525static PyObject *
6526win32_startfile(PyObject *self, PyObject *args)
6527{
6528 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00006529 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006530 HINSTANCE rc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006531#ifdef Py_WIN_WIDE_FILENAMES
6532 if (unicode_file_names()) {
6533 PyObject *unipath, *woperation = NULL;
6534 if (!PyArg_ParseTuple(args, "U|s:startfile",
6535 &unipath, &operation)) {
6536 PyErr_Clear();
6537 goto normal;
6538 }
6539
6540
6541 if (operation) {
6542 woperation = PyUnicode_DecodeASCII(operation,
6543 strlen(operation), NULL);
6544 if (!woperation) {
6545 PyErr_Clear();
6546 operation = NULL;
6547 goto normal;
6548 }
6549 }
6550
6551 Py_BEGIN_ALLOW_THREADS
6552 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6553 PyUnicode_AS_UNICODE(unipath),
6554 NULL, NULL, SW_SHOWNORMAL);
6555 Py_END_ALLOW_THREADS
6556
6557 Py_XDECREF(woperation);
6558 if (rc <= (HINSTANCE)32) {
6559 PyObject *errval = win32_error_unicode("startfile",
6560 PyUnicode_AS_UNICODE(unipath));
6561 return errval;
6562 }
6563 Py_INCREF(Py_None);
6564 return Py_None;
6565 }
6566#endif
6567
6568normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00006569 if (!PyArg_ParseTuple(args, "et|s:startfile",
6570 Py_FileSystemDefaultEncoding, &filepath,
6571 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00006572 return NULL;
6573 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00006574 rc = ShellExecute((HWND)0, operation, filepath,
6575 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006576 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00006577 if (rc <= (HINSTANCE)32) {
6578 PyObject *errval = win32_error("startfile", filepath);
6579 PyMem_Free(filepath);
6580 return errval;
6581 }
6582 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006583 Py_INCREF(Py_None);
6584 return Py_None;
6585}
6586#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006587
Martin v. Löwis438b5342002-12-27 10:16:42 +00006588#ifdef HAVE_GETLOADAVG
6589PyDoc_STRVAR(posix_getloadavg__doc__,
6590"getloadavg() -> (float, float, float)\n\n\
6591Return the number of processes in the system run queue averaged over\n\
6592the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6593was unobtainable");
6594
6595static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006596posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006597{
6598 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006599 if (getloadavg(loadavg, 3)!=3) {
6600 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6601 return NULL;
6602 } else
6603 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6604}
6605#endif
6606
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006607#ifdef MS_WINDOWS
6608
6609PyDoc_STRVAR(win32_urandom__doc__,
6610"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006611Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006612
6613typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6614 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6615 DWORD dwFlags );
6616typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6617 BYTE *pbBuffer );
6618
6619static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00006620/* This handle is never explicitly released. Instead, the operating
6621 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006622static HCRYPTPROV hCryptProv = 0;
6623
Tim Peters4ad82172004-08-30 17:02:04 +00006624static PyObject*
6625win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006626{
Tim Petersd3115382004-08-30 17:36:46 +00006627 int howMany;
6628 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006629
Tim Peters4ad82172004-08-30 17:02:04 +00006630 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00006631 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00006632 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00006633 if (howMany < 0)
6634 return PyErr_Format(PyExc_ValueError,
6635 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006636
Tim Peters4ad82172004-08-30 17:02:04 +00006637 if (hCryptProv == 0) {
6638 HINSTANCE hAdvAPI32 = NULL;
6639 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006640
Tim Peters4ad82172004-08-30 17:02:04 +00006641 /* Obtain handle to the DLL containing CryptoAPI
6642 This should not fail */
6643 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6644 if(hAdvAPI32 == NULL)
6645 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006646
Tim Peters4ad82172004-08-30 17:02:04 +00006647 /* Obtain pointers to the CryptoAPI functions
6648 This will fail on some early versions of Win95 */
6649 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6650 hAdvAPI32,
6651 "CryptAcquireContextA");
6652 if (pCryptAcquireContext == NULL)
6653 return PyErr_Format(PyExc_NotImplementedError,
6654 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006655
Tim Peters4ad82172004-08-30 17:02:04 +00006656 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6657 hAdvAPI32, "CryptGenRandom");
Thomas Wouters89f507f2006-12-13 04:49:30 +00006658 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00006659 return PyErr_Format(PyExc_NotImplementedError,
6660 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006661
Tim Peters4ad82172004-08-30 17:02:04 +00006662 /* Acquire context */
6663 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
6664 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
6665 return win32_error("CryptAcquireContext", NULL);
6666 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006667
Tim Peters4ad82172004-08-30 17:02:04 +00006668 /* Allocate bytes */
Christian Heimes72b710a2008-05-26 13:28:38 +00006669 result = PyBytes_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00006670 if (result != NULL) {
6671 /* Get random data */
Amaury Forgeot d'Arca05ada32008-07-21 21:13:14 +00006672 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00006673 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Christian Heimes72b710a2008-05-26 13:28:38 +00006674 PyBytes_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00006675 Py_DECREF(result);
6676 return win32_error("CryptGenRandom", NULL);
6677 }
Tim Peters4ad82172004-08-30 17:02:04 +00006678 }
Tim Petersd3115382004-08-30 17:36:46 +00006679 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006680}
6681#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00006682
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006683PyDoc_STRVAR(device_encoding__doc__,
6684"device_encoding(fd) -> str\n\n\
6685Return a string describing the encoding of the device\n\
6686if the output is a terminal; else return None.");
6687
6688static PyObject *
6689device_encoding(PyObject *self, PyObject *args)
6690{
6691 int fd;
6692 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
6693 return NULL;
6694 if (!isatty(fd)) {
6695 Py_INCREF(Py_None);
6696 return Py_None;
6697 }
6698#if defined(MS_WINDOWS) || defined(MS_WIN64)
6699 if (fd == 0) {
6700 char buf[100];
6701 sprintf(buf, "cp%d", GetConsoleCP());
6702 return PyUnicode_FromString(buf);
6703 }
6704 if (fd == 1 || fd == 2) {
6705 char buf[100];
6706 sprintf(buf, "cp%d", GetConsoleOutputCP());
6707 return PyUnicode_FromString(buf);
6708 }
6709#elif defined(CODESET)
6710 {
6711 char *codeset = nl_langinfo(CODESET);
6712 if (codeset)
6713 return PyUnicode_FromString(codeset);
6714 }
6715#endif
6716 Py_INCREF(Py_None);
6717 return Py_None;
6718}
6719
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006720#ifdef __VMS
6721/* Use openssl random routine */
6722#include <openssl/rand.h>
6723PyDoc_STRVAR(vms_urandom__doc__,
6724"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006725Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006726
6727static PyObject*
6728vms_urandom(PyObject *self, PyObject *args)
6729{
6730 int howMany;
6731 PyObject* result;
6732
6733 /* Read arguments */
6734 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
6735 return NULL;
6736 if (howMany < 0)
6737 return PyErr_Format(PyExc_ValueError,
6738 "negative argument not allowed");
6739
6740 /* Allocate bytes */
Christian Heimes72b710a2008-05-26 13:28:38 +00006741 result = PyBytes_FromStringAndSize(NULL, howMany);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006742 if (result != NULL) {
6743 /* Get random data */
6744 if (RAND_pseudo_bytes((unsigned char*)
Christian Heimes72b710a2008-05-26 13:28:38 +00006745 PyBytes_AS_STRING(result),
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006746 howMany) < 0) {
6747 Py_DECREF(result);
6748 return PyErr_Format(PyExc_ValueError,
6749 "RAND_pseudo_bytes");
6750 }
6751 }
6752 return result;
6753}
6754#endif
6755
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006756static PyMethodDef posix_methods[] = {
6757 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6758#ifdef HAVE_TTYNAME
6759 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6760#endif
6761 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00006762#ifdef HAVE_CHFLAGS
6763 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
6764#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006765 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00006766#ifdef HAVE_FCHMOD
6767 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
6768#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006769#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006770 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006771#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00006772#ifdef HAVE_LCHMOD
6773 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
6774#endif /* HAVE_LCHMOD */
6775#ifdef HAVE_FCHOWN
6776 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
6777#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00006778#ifdef HAVE_LCHFLAGS
6779 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
6780#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006781#ifdef HAVE_LCHOWN
6782 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6783#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006784#ifdef HAVE_CHROOT
6785 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6786#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006787#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006788 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006789#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006790#ifdef HAVE_GETCWD
Guido van Rossumf0af3e32008-10-02 18:55:37 +00006791 {"getcwd", (PyCFunction)posix_getcwd_unicode,
6792 METH_NOARGS, posix_getcwd__doc__},
6793 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
6794 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006795#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006796#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006797 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006798#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006799 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6800 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6801 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006802#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006803 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006804#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006805#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006806 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006807#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006808 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6809 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6810 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006811 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006812#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006813 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006814#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006815#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006816 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006817#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006818 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006819#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00006820 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006821#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006822 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6823 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6824 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006825#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00006826 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006827#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006828 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006829#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006830 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6831 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006832#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006833#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006834 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6835 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006836#if defined(PYOS_OS2)
6837 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
6838 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
6839#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00006840#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006841#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00006842 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006843#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006844#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00006845 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006846#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006847#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00006848 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006849#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006850#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00006851 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00006852#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006853#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006854 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006855#endif /* HAVE_GETEGID */
6856#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006857 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006858#endif /* HAVE_GETEUID */
6859#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006860 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006861#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006862#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00006863 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00006864#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00006865 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006866#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006867 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006868#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006869#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00006870 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006871#endif /* HAVE_GETPPID */
6872#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006873 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006874#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006875#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00006876 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00006877#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006878#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006879 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006880#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006881#ifdef HAVE_KILLPG
6882 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6883#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006884#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006885 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006886#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00006887#ifdef MS_WINDOWS
6888 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
6889#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006890#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006891 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006892#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006893#ifdef HAVE_SETEUID
6894 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6895#endif /* HAVE_SETEUID */
6896#ifdef HAVE_SETEGID
6897 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6898#endif /* HAVE_SETEGID */
6899#ifdef HAVE_SETREUID
6900 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6901#endif /* HAVE_SETREUID */
6902#ifdef HAVE_SETREGID
6903 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6904#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006905#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006906 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006907#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006908#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006909 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006910#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006911#ifdef HAVE_GETPGID
6912 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6913#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006914#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006915 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006916#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006917#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00006918 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006919#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006920#ifdef HAVE_WAIT3
6921 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
6922#endif /* HAVE_WAIT3 */
6923#ifdef HAVE_WAIT4
6924 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
6925#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00006926#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006927 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006928#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006929#ifdef HAVE_GETSID
6930 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
6931#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006932#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00006933 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006934#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006935#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006936 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006937#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006938#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006939 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006940#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006941#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006942 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006943#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006944 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6945 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Christian Heimesfdab48e2008-01-20 09:06:41 +00006946 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006947 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006948 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6949 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6950 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6951 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6952 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6953 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006954 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006955#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00006956 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006957#endif
6958#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006959 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006960#endif
Neal Norwitz11690112002-07-30 01:08:28 +00006961#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006962 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6963#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006964#ifdef HAVE_DEVICE_MACROS
6965 {"major", posix_major, METH_VARARGS, posix_major__doc__},
6966 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
6967 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
6968#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006969#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006970 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006971#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006972#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006973 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006974#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006975#ifdef HAVE_UNSETENV
6976 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6977#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006978 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00006979#ifdef HAVE_FCHDIR
6980 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6981#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006982#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006983 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006984#endif
6985#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006986 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006987#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006988#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006989#ifdef WCOREDUMP
6990 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6991#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006992#ifdef WIFCONTINUED
6993 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6994#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006995#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006996 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006997#endif /* WIFSTOPPED */
6998#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006999 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007000#endif /* WIFSIGNALED */
7001#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007002 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007003#endif /* WIFEXITED */
7004#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007005 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007006#endif /* WEXITSTATUS */
7007#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007008 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007009#endif /* WTERMSIG */
7010#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007011 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007012#endif /* WSTOPSIG */
7013#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007014#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007015 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007016#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007017#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007018 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007019#endif
Fred Drakec9680921999-12-13 16:37:25 +00007020#ifdef HAVE_CONFSTR
7021 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7022#endif
7023#ifdef HAVE_SYSCONF
7024 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7025#endif
7026#ifdef HAVE_FPATHCONF
7027 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7028#endif
7029#ifdef HAVE_PATHCONF
7030 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7031#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007032 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007033#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007034 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7035#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007036#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007037 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007038#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007039 #ifdef MS_WINDOWS
7040 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7041 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007042 #ifdef __VMS
7043 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
7044 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007045 {NULL, NULL} /* Sentinel */
7046};
7047
7048
Barry Warsaw4a342091996-12-19 23:50:02 +00007049static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007050ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007051{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007052 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007053}
7054
Guido van Rossumd48f2521997-12-05 22:19:34 +00007055#if defined(PYOS_OS2)
7056/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007057static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007058{
7059 APIRET rc;
7060 ULONG values[QSV_MAX+1];
7061 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007062 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007063
7064 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007065 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007066 Py_END_ALLOW_THREADS
7067
7068 if (rc != NO_ERROR) {
7069 os2_error(rc);
7070 return -1;
7071 }
7072
Fred Drake4d1e64b2002-04-15 19:40:07 +00007073 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7074 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7075 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7076 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7077 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7078 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7079 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007080
7081 switch (values[QSV_VERSION_MINOR]) {
7082 case 0: ver = "2.00"; break;
7083 case 10: ver = "2.10"; break;
7084 case 11: ver = "2.11"; break;
7085 case 30: ver = "3.00"; break;
7086 case 40: ver = "4.00"; break;
7087 case 50: ver = "5.00"; break;
7088 default:
Tim Peters885d4572001-11-28 20:27:42 +00007089 PyOS_snprintf(tmp, sizeof(tmp),
7090 "%d-%d", values[QSV_VERSION_MAJOR],
7091 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007092 ver = &tmp[0];
7093 }
7094
7095 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007096 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007097 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007098
7099 /* Add Indicator of Which Drive was Used to Boot the System */
7100 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7101 tmp[1] = ':';
7102 tmp[2] = '\0';
7103
Fred Drake4d1e64b2002-04-15 19:40:07 +00007104 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007105}
7106#endif
7107
Barry Warsaw4a342091996-12-19 23:50:02 +00007108static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007109all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007110{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007111#ifdef F_OK
7112 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007113#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007114#ifdef R_OK
7115 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007116#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007117#ifdef W_OK
7118 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007119#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007120#ifdef X_OK
7121 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007122#endif
Fred Drakec9680921999-12-13 16:37:25 +00007123#ifdef NGROUPS_MAX
7124 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7125#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007126#ifdef TMP_MAX
7127 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7128#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007129#ifdef WCONTINUED
7130 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7131#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007132#ifdef WNOHANG
7133 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007134#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007135#ifdef WUNTRACED
7136 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7137#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007138#ifdef O_RDONLY
7139 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7140#endif
7141#ifdef O_WRONLY
7142 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7143#endif
7144#ifdef O_RDWR
7145 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7146#endif
7147#ifdef O_NDELAY
7148 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7149#endif
7150#ifdef O_NONBLOCK
7151 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7152#endif
7153#ifdef O_APPEND
7154 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7155#endif
7156#ifdef O_DSYNC
7157 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7158#endif
7159#ifdef O_RSYNC
7160 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7161#endif
7162#ifdef O_SYNC
7163 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7164#endif
7165#ifdef O_NOCTTY
7166 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7167#endif
7168#ifdef O_CREAT
7169 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7170#endif
7171#ifdef O_EXCL
7172 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7173#endif
7174#ifdef O_TRUNC
7175 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7176#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007177#ifdef O_BINARY
7178 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7179#endif
7180#ifdef O_TEXT
7181 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7182#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007183#ifdef O_LARGEFILE
7184 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7185#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007186#ifdef O_SHLOCK
7187 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7188#endif
7189#ifdef O_EXLOCK
7190 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7191#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007192
Tim Peters5aa91602002-01-30 05:46:57 +00007193/* MS Windows */
7194#ifdef O_NOINHERIT
7195 /* Don't inherit in child processes. */
7196 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7197#endif
7198#ifdef _O_SHORT_LIVED
7199 /* Optimize for short life (keep in memory). */
7200 /* MS forgot to define this one with a non-underscore form too. */
7201 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7202#endif
7203#ifdef O_TEMPORARY
7204 /* Automatically delete when last handle is closed. */
7205 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7206#endif
7207#ifdef O_RANDOM
7208 /* Optimize for random access. */
7209 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7210#endif
7211#ifdef O_SEQUENTIAL
7212 /* Optimize for sequential access. */
7213 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7214#endif
7215
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007216/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00007217#ifdef O_ASYNC
7218 /* Send a SIGIO signal whenever input or output
7219 becomes available on file descriptor */
7220 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
7221#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007222#ifdef O_DIRECT
7223 /* Direct disk access. */
7224 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7225#endif
7226#ifdef O_DIRECTORY
7227 /* Must be a directory. */
7228 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7229#endif
7230#ifdef O_NOFOLLOW
7231 /* Do not follow links. */
7232 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7233#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00007234#ifdef O_NOATIME
7235 /* Do not update the access time. */
7236 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
7237#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007238
Barry Warsaw5676bd12003-01-07 20:57:09 +00007239 /* These come from sysexits.h */
7240#ifdef EX_OK
7241 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007242#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007243#ifdef EX_USAGE
7244 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007245#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007246#ifdef EX_DATAERR
7247 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007248#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007249#ifdef EX_NOINPUT
7250 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007251#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007252#ifdef EX_NOUSER
7253 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007254#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007255#ifdef EX_NOHOST
7256 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007257#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007258#ifdef EX_UNAVAILABLE
7259 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007260#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007261#ifdef EX_SOFTWARE
7262 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007263#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007264#ifdef EX_OSERR
7265 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007266#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007267#ifdef EX_OSFILE
7268 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007269#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007270#ifdef EX_CANTCREAT
7271 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007272#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007273#ifdef EX_IOERR
7274 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007275#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007276#ifdef EX_TEMPFAIL
7277 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007278#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007279#ifdef EX_PROTOCOL
7280 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007281#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007282#ifdef EX_NOPERM
7283 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007284#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007285#ifdef EX_CONFIG
7286 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007287#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007288#ifdef EX_NOTFOUND
7289 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007290#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007291
Guido van Rossum246bc171999-02-01 23:54:31 +00007292#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007293#if defined(PYOS_OS2) && defined(PYCC_GCC)
7294 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7295 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7296 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7297 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7298 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7299 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7300 if (ins(d, "P_PM", (long)P_PM)) return -1;
7301 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7302 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7303 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7304 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7305 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7306 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7307 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7308 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7309 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7310 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7311 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7312 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7313 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7314#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007315 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7316 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7317 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7318 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7319 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007320#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007321#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007322
Guido van Rossumd48f2521997-12-05 22:19:34 +00007323#if defined(PYOS_OS2)
7324 if (insertvalues(d)) return -1;
7325#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007326 return 0;
7327}
7328
7329
Tim Peters5aa91602002-01-30 05:46:57 +00007330#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007331#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007332#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007333
7334#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007335#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007336#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007337
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007338#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00007339#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007340#define MODNAME "posix"
7341#endif
7342
Martin v. Löwis1a214512008-06-11 05:26:20 +00007343static struct PyModuleDef posixmodule = {
7344 PyModuleDef_HEAD_INIT,
7345 MODNAME,
7346 posix__doc__,
7347 -1,
7348 posix_methods,
7349 NULL,
7350 NULL,
7351 NULL,
7352 NULL
7353};
7354
7355
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007356PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007357INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007358{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007359 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007360
Martin v. Löwis1a214512008-06-11 05:26:20 +00007361 m = PyModule_Create(&posixmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00007362 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007363 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007364
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007365 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007366 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007367 Py_XINCREF(v);
7368 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007369 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00007370 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007371
Fred Drake4d1e64b2002-04-15 19:40:07 +00007372 if (all_ins(m))
Martin v. Löwis1a214512008-06-11 05:26:20 +00007373 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00007374
Fred Drake4d1e64b2002-04-15 19:40:07 +00007375 if (setup_confname_tables(m))
Martin v. Löwis1a214512008-06-11 05:26:20 +00007376 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00007377
Fred Drake4d1e64b2002-04-15 19:40:07 +00007378 Py_INCREF(PyExc_OSError);
7379 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007380
Guido van Rossumb3d39562000-01-31 18:41:26 +00007381#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007382 if (posix_putenv_garbage == NULL)
7383 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007384#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007385
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007386 if (!initialized) {
7387 stat_result_desc.name = MODNAME ".stat_result";
7388 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7389 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7390 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7391 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7392 structseq_new = StatResultType.tp_new;
7393 StatResultType.tp_new = statresult_new;
7394
7395 statvfs_result_desc.name = MODNAME ".statvfs_result";
7396 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
7397 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007398 Py_INCREF((PyObject*) &StatResultType);
7399 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007400 Py_INCREF((PyObject*) &StatVFSResultType);
7401 PyModule_AddObject(m, "statvfs_result",
7402 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007403 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007404
7405#ifdef __APPLE__
7406 /*
7407 * Step 2 of weak-linking support on Mac OS X.
7408 *
7409 * The code below removes functions that are not available on the
7410 * currently active platform.
7411 *
7412 * This block allow one to use a python binary that was build on
7413 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7414 * OSX 10.4.
7415 */
7416#ifdef HAVE_FSTATVFS
7417 if (fstatvfs == NULL) {
7418 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007419 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007420 }
7421 }
7422#endif /* HAVE_FSTATVFS */
7423
7424#ifdef HAVE_STATVFS
7425 if (statvfs == NULL) {
7426 if (PyObject_DelAttrString(m, "statvfs") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007427 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007428 }
7429 }
7430#endif /* HAVE_STATVFS */
7431
7432# ifdef HAVE_LCHOWN
7433 if (lchown == NULL) {
7434 if (PyObject_DelAttrString(m, "lchown") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007435 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007436 }
7437 }
7438#endif /* HAVE_LCHOWN */
7439
7440
7441#endif /* __APPLE__ */
Martin v. Löwis1a214512008-06-11 05:26:20 +00007442 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007443
Guido van Rossumb6775db1994-08-01 11:34:53 +00007444}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007445
7446#ifdef __cplusplus
7447}
7448#endif