blob: c725b7d2ddfc5866e7c9438e46d1eee874538972 [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) {
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000754 new_path = malloc(result * sizeof(wchar_t));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000755 if (!new_path) {
756 SetLastError(ERROR_OUTOFMEMORY);
757 return FALSE;
758 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000759 result = GetCurrentDirectoryW(result, new_path);
760 if (!result) {
761 free(new_path);
762 return FALSE;
763 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000764 }
765 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
766 wcsncmp(new_path, L"//", 2) == 0)
767 /* UNC path, nothing to do. */
768 return TRUE;
769 env[1] = new_path[0];
770 result = SetEnvironmentVariableW(env, new_path);
771 if (new_path != _new_path)
772 free(new_path);
773 return result;
774}
775#endif
776
Martin v. Löwis14694662006-02-03 12:54:16 +0000777#ifdef MS_WINDOWS
778/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
779 - time stamps are restricted to second resolution
780 - file modification times suffer from forth-and-back conversions between
781 UTC and local time
782 Therefore, we implement our own stat, based on the Win32 API directly.
783*/
784#define HAVE_STAT_NSEC 1
785
786struct win32_stat{
787 int st_dev;
788 __int64 st_ino;
789 unsigned short st_mode;
790 int st_nlink;
791 int st_uid;
792 int st_gid;
793 int st_rdev;
794 __int64 st_size;
795 int st_atime;
796 int st_atime_nsec;
797 int st_mtime;
798 int st_mtime_nsec;
799 int st_ctime;
800 int st_ctime_nsec;
801};
802
803static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
804
805static void
806FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
807{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000808 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
809 /* Cannot simply cast and dereference in_ptr,
810 since it might not be aligned properly */
811 __int64 in;
812 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000813 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
814 /* XXX Win32 supports time stamps past 2038; we currently don't */
815 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
816}
817
Thomas Wouters477c8d52006-05-27 19:21:47 +0000818static void
819time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
820{
821 /* XXX endianness */
822 __int64 out;
823 out = time_in + secs_between_epochs;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000824 out = out * 10000000 + nsec_in / 100;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000825 memcpy(out_ptr, &out, sizeof(out));
826}
827
Martin v. Löwis14694662006-02-03 12:54:16 +0000828/* Below, we *know* that ugo+r is 0444 */
829#if _S_IREAD != 0400
830#error Unsupported C library
831#endif
832static int
833attributes_to_mode(DWORD attr)
834{
835 int m = 0;
836 if (attr & FILE_ATTRIBUTE_DIRECTORY)
837 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
838 else
839 m |= _S_IFREG;
840 if (attr & FILE_ATTRIBUTE_READONLY)
841 m |= 0444;
842 else
843 m |= 0666;
844 return m;
845}
846
847static int
848attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
849{
850 memset(result, 0, sizeof(*result));
851 result->st_mode = attributes_to_mode(info->dwFileAttributes);
852 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
853 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
854 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
855 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
856
857 return 0;
858}
859
Thomas Wouters89f507f2006-12-13 04:49:30 +0000860/* Emulate GetFileAttributesEx[AW] on Windows 95 */
861static int checked = 0;
862static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
863static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
864static void
865check_gfax()
866{
867 HINSTANCE hKernel32;
868 if (checked)
869 return;
870 checked = 1;
871 hKernel32 = GetModuleHandle("KERNEL32");
872 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
873 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
874}
875
Guido van Rossumd8faa362007-04-27 19:54:29 +0000876static BOOL
877attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
878{
879 HANDLE hFindFile;
880 WIN32_FIND_DATAA FileData;
881 hFindFile = FindFirstFileA(pszFile, &FileData);
882 if (hFindFile == INVALID_HANDLE_VALUE)
883 return FALSE;
884 FindClose(hFindFile);
885 pfad->dwFileAttributes = FileData.dwFileAttributes;
886 pfad->ftCreationTime = FileData.ftCreationTime;
887 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
888 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
889 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
890 pfad->nFileSizeLow = FileData.nFileSizeLow;
891 return TRUE;
892}
893
894static BOOL
895attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
896{
897 HANDLE hFindFile;
898 WIN32_FIND_DATAW FileData;
899 hFindFile = FindFirstFileW(pszFile, &FileData);
900 if (hFindFile == INVALID_HANDLE_VALUE)
901 return FALSE;
902 FindClose(hFindFile);
903 pfad->dwFileAttributes = FileData.dwFileAttributes;
904 pfad->ftCreationTime = FileData.ftCreationTime;
905 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
906 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
907 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
908 pfad->nFileSizeLow = FileData.nFileSizeLow;
909 return TRUE;
910}
911
Thomas Wouters89f507f2006-12-13 04:49:30 +0000912static BOOL WINAPI
913Py_GetFileAttributesExA(LPCSTR pszFile,
914 GET_FILEEX_INFO_LEVELS level,
915 LPVOID pv)
916{
917 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000918 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
919 /* First try to use the system's implementation, if that is
920 available and either succeeds to gives an error other than
921 that it isn't implemented. */
922 check_gfax();
923 if (gfaxa) {
924 result = gfaxa(pszFile, level, pv);
925 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
926 return result;
927 }
928 /* It's either not present, or not implemented.
929 Emulate using FindFirstFile. */
930 if (level != GetFileExInfoStandard) {
931 SetLastError(ERROR_INVALID_PARAMETER);
932 return FALSE;
933 }
934 /* Use GetFileAttributes to validate that the file name
935 does not contain wildcards (which FindFirstFile would
936 accept). */
937 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
938 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000939 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000940}
941
942static BOOL WINAPI
943Py_GetFileAttributesExW(LPCWSTR pszFile,
944 GET_FILEEX_INFO_LEVELS level,
945 LPVOID pv)
946{
947 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000948 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
949 /* First try to use the system's implementation, if that is
950 available and either succeeds to gives an error other than
951 that it isn't implemented. */
952 check_gfax();
953 if (gfaxa) {
954 result = gfaxw(pszFile, level, pv);
955 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
956 return result;
957 }
958 /* It's either not present, or not implemented.
959 Emulate using FindFirstFile. */
960 if (level != GetFileExInfoStandard) {
961 SetLastError(ERROR_INVALID_PARAMETER);
962 return FALSE;
963 }
964 /* Use GetFileAttributes to validate that the file name
965 does not contain wildcards (which FindFirstFile would
966 accept). */
967 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
968 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000969 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000970}
971
Martin v. Löwis14694662006-02-03 12:54:16 +0000972static int
973win32_stat(const char* path, struct win32_stat *result)
974{
975 WIN32_FILE_ATTRIBUTE_DATA info;
976 int code;
977 char *dot;
978 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +0000979 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +0000980 if (GetLastError() != ERROR_SHARING_VIOLATION) {
981 /* Protocol violation: we explicitly clear errno, instead of
982 setting it to a POSIX error. Callers should use GetLastError. */
983 errno = 0;
984 return -1;
985 } else {
986 /* Could not get attributes on open file. Fall back to
987 reading the directory. */
988 if (!attributes_from_dir(path, &info)) {
989 /* Very strange. This should not fail now */
990 errno = 0;
991 return -1;
992 }
993 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000994 }
995 code = attribute_data_to_stat(&info, result);
996 if (code != 0)
997 return code;
998 /* Set S_IFEXEC if it is an .exe, .bat, ... */
999 dot = strrchr(path, '.');
1000 if (dot) {
1001 if (stricmp(dot, ".bat") == 0 ||
1002 stricmp(dot, ".cmd") == 0 ||
1003 stricmp(dot, ".exe") == 0 ||
1004 stricmp(dot, ".com") == 0)
1005 result->st_mode |= 0111;
1006 }
1007 return code;
1008}
1009
1010static int
1011win32_wstat(const wchar_t* path, struct win32_stat *result)
1012{
1013 int code;
1014 const wchar_t *dot;
1015 WIN32_FILE_ATTRIBUTE_DATA info;
1016 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001017 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001018 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1019 /* Protocol violation: we explicitly clear errno, instead of
1020 setting it to a POSIX error. Callers should use GetLastError. */
1021 errno = 0;
1022 return -1;
1023 } else {
1024 /* Could not get attributes on open file. Fall back to
1025 reading the directory. */
1026 if (!attributes_from_dir_w(path, &info)) {
1027 /* Very strange. This should not fail now */
1028 errno = 0;
1029 return -1;
1030 }
1031 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001032 }
1033 code = attribute_data_to_stat(&info, result);
1034 if (code < 0)
1035 return code;
1036 /* Set IFEXEC if it is an .exe, .bat, ... */
1037 dot = wcsrchr(path, '.');
1038 if (dot) {
1039 if (_wcsicmp(dot, L".bat") == 0 ||
1040 _wcsicmp(dot, L".cmd") == 0 ||
1041 _wcsicmp(dot, L".exe") == 0 ||
1042 _wcsicmp(dot, L".com") == 0)
1043 result->st_mode |= 0111;
1044 }
1045 return code;
1046}
1047
1048static int
1049win32_fstat(int file_number, struct win32_stat *result)
1050{
1051 BY_HANDLE_FILE_INFORMATION info;
1052 HANDLE h;
1053 int type;
1054
1055 h = (HANDLE)_get_osfhandle(file_number);
1056
1057 /* Protocol violation: we explicitly clear errno, instead of
1058 setting it to a POSIX error. Callers should use GetLastError. */
1059 errno = 0;
1060
1061 if (h == INVALID_HANDLE_VALUE) {
1062 /* This is really a C library error (invalid file handle).
1063 We set the Win32 error to the closes one matching. */
1064 SetLastError(ERROR_INVALID_HANDLE);
1065 return -1;
1066 }
1067 memset(result, 0, sizeof(*result));
1068
1069 type = GetFileType(h);
1070 if (type == FILE_TYPE_UNKNOWN) {
1071 DWORD error = GetLastError();
1072 if (error != 0) {
1073 return -1;
1074 }
1075 /* else: valid but unknown file */
1076 }
1077
1078 if (type != FILE_TYPE_DISK) {
1079 if (type == FILE_TYPE_CHAR)
1080 result->st_mode = _S_IFCHR;
1081 else if (type == FILE_TYPE_PIPE)
1082 result->st_mode = _S_IFIFO;
1083 return 0;
1084 }
1085
1086 if (!GetFileInformationByHandle(h, &info)) {
1087 return -1;
1088 }
1089
1090 /* similar to stat() */
1091 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1092 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1093 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1094 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1095 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1096 /* specific to fstat() */
1097 result->st_nlink = info.nNumberOfLinks;
1098 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1099 return 0;
1100}
1101
1102#endif /* MS_WINDOWS */
1103
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001104PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001105"stat_result: Result from stat or lstat.\n\n\
1106This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001107 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001108or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1109\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001110Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1111or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001112\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001113See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001114
1115static PyStructSequence_Field stat_result_fields[] = {
1116 {"st_mode", "protection bits"},
1117 {"st_ino", "inode"},
1118 {"st_dev", "device"},
1119 {"st_nlink", "number of hard links"},
1120 {"st_uid", "user ID of owner"},
1121 {"st_gid", "group ID of owner"},
1122 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001123 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1124 {NULL, "integer time of last access"},
1125 {NULL, "integer time of last modification"},
1126 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001127 {"st_atime", "time of last access"},
1128 {"st_mtime", "time of last modification"},
1129 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001130#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001131 {"st_blksize", "blocksize for filesystem I/O"},
1132#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001133#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001134 {"st_blocks", "number of blocks allocated"},
1135#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001136#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001137 {"st_rdev", "device type (if inode device)"},
1138#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001139#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1140 {"st_flags", "user defined flags for file"},
1141#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001142#ifdef HAVE_STRUCT_STAT_ST_GEN
1143 {"st_gen", "generation number"},
1144#endif
1145#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1146 {"st_birthtime", "time of creation"},
1147#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001148 {0}
1149};
1150
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001151#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001152#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001153#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001154#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001155#endif
1156
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001157#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001158#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1159#else
1160#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1161#endif
1162
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001163#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001164#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1165#else
1166#define ST_RDEV_IDX ST_BLOCKS_IDX
1167#endif
1168
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001169#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1170#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1171#else
1172#define ST_FLAGS_IDX ST_RDEV_IDX
1173#endif
1174
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001175#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001176#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001177#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001178#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001179#endif
1180
1181#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1182#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1183#else
1184#define ST_BIRTHTIME_IDX ST_GEN_IDX
1185#endif
1186
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001187static PyStructSequence_Desc stat_result_desc = {
1188 "stat_result", /* name */
1189 stat_result__doc__, /* doc */
1190 stat_result_fields,
1191 10
1192};
1193
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001194PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001195"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1196This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001197 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001198or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001199\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001200See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001201
1202static PyStructSequence_Field statvfs_result_fields[] = {
1203 {"f_bsize", },
1204 {"f_frsize", },
1205 {"f_blocks", },
1206 {"f_bfree", },
1207 {"f_bavail", },
1208 {"f_files", },
1209 {"f_ffree", },
1210 {"f_favail", },
1211 {"f_flag", },
1212 {"f_namemax",},
1213 {0}
1214};
1215
1216static PyStructSequence_Desc statvfs_result_desc = {
1217 "statvfs_result", /* name */
1218 statvfs_result__doc__, /* doc */
1219 statvfs_result_fields,
1220 10
1221};
1222
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001223static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001224static PyTypeObject StatResultType;
1225static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001226static newfunc structseq_new;
1227
1228static PyObject *
1229statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1230{
1231 PyStructSequence *result;
1232 int i;
1233
1234 result = (PyStructSequence*)structseq_new(type, args, kwds);
1235 if (!result)
1236 return NULL;
1237 /* If we have been initialized from a tuple,
1238 st_?time might be set to None. Initialize it
1239 from the int slots. */
1240 for (i = 7; i <= 9; i++) {
1241 if (result->ob_item[i+3] == Py_None) {
1242 Py_DECREF(Py_None);
1243 Py_INCREF(result->ob_item[i]);
1244 result->ob_item[i+3] = result->ob_item[i];
1245 }
1246 }
1247 return (PyObject*)result;
1248}
1249
1250
1251
1252/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001253static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001254
1255PyDoc_STRVAR(stat_float_times__doc__,
1256"stat_float_times([newval]) -> oldval\n\n\
1257Determine whether os.[lf]stat represents time stamps as float objects.\n\
1258If newval is True, future calls to stat() return floats, if it is False,\n\
1259future calls return ints. \n\
1260If newval is omitted, return the current setting.\n");
1261
1262static PyObject*
1263stat_float_times(PyObject* self, PyObject *args)
1264{
1265 int newval = -1;
1266 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1267 return NULL;
1268 if (newval == -1)
1269 /* Return old value */
1270 return PyBool_FromLong(_stat_float_times);
1271 _stat_float_times = newval;
1272 Py_INCREF(Py_None);
1273 return Py_None;
1274}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001275
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001276static void
1277fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1278{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001279 PyObject *fval,*ival;
1280#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001281 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001282#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001283 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001284#endif
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001285 if (!ival)
1286 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001287 if (_stat_float_times) {
1288 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1289 } else {
1290 fval = ival;
1291 Py_INCREF(fval);
1292 }
1293 PyStructSequence_SET_ITEM(v, index, ival);
1294 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001295}
1296
Tim Peters5aa91602002-01-30 05:46:57 +00001297/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001298 (used by posix_stat() and posix_fstat()) */
1299static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001300_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001301{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001302 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001303 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001304 if (v == NULL)
1305 return NULL;
1306
Christian Heimes217cfd12007-12-02 14:31:20 +00001307 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001308#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001309 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001310 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001311#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001312 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001313#endif
1314#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001315 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001316 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001317#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001318 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001319#endif
Christian Heimes217cfd12007-12-02 14:31:20 +00001320 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1321 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1322 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001323#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001324 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001325 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001326#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001327 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001328#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001329
Martin v. Löwis14694662006-02-03 12:54:16 +00001330#if defined(HAVE_STAT_TV_NSEC)
1331 ansec = st->st_atim.tv_nsec;
1332 mnsec = st->st_mtim.tv_nsec;
1333 cnsec = st->st_ctim.tv_nsec;
1334#elif defined(HAVE_STAT_TV_NSEC2)
1335 ansec = st->st_atimespec.tv_nsec;
1336 mnsec = st->st_mtimespec.tv_nsec;
1337 cnsec = st->st_ctimespec.tv_nsec;
1338#elif defined(HAVE_STAT_NSEC)
1339 ansec = st->st_atime_nsec;
1340 mnsec = st->st_mtime_nsec;
1341 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001342#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001343 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001344#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001345 fill_time(v, 7, st->st_atime, ansec);
1346 fill_time(v, 8, st->st_mtime, mnsec);
1347 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001348
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001349#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001350 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001351 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001352#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001353#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001354 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001355 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001356#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001357#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001358 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001359 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001360#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001361#ifdef HAVE_STRUCT_STAT_ST_GEN
1362 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001363 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001364#endif
1365#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1366 {
1367 PyObject *val;
1368 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001369 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001370#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001371 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001372#else
1373 bnsec = 0;
1374#endif
1375 if (_stat_float_times) {
1376 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1377 } else {
Christian Heimes217cfd12007-12-02 14:31:20 +00001378 val = PyLong_FromLong((long)bsec);
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001379 }
1380 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1381 val);
1382 }
1383#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001384#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1385 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001386 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001387#endif
Fred Drake699f3522000-06-29 21:12:41 +00001388
1389 if (PyErr_Occurred()) {
1390 Py_DECREF(v);
1391 return NULL;
1392 }
1393
1394 return v;
1395}
1396
Martin v. Löwisd8948722004-06-02 09:57:56 +00001397#ifdef MS_WINDOWS
1398
1399/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1400 where / can be used in place of \ and the trailing slash is optional.
1401 Both SERVER and SHARE must have at least one character.
1402*/
1403
1404#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1405#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001406#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001407#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001408#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001409
Tim Peters4ad82172004-08-30 17:02:04 +00001410static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001411IsUNCRootA(char *path, int pathlen)
1412{
1413 #define ISSLASH ISSLASHA
1414
1415 int i, share;
1416
1417 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1418 /* minimum UNCRoot is \\x\y */
1419 return FALSE;
1420 for (i = 2; i < pathlen ; i++)
1421 if (ISSLASH(path[i])) break;
1422 if (i == 2 || i == pathlen)
1423 /* do not allow \\\SHARE or \\SERVER */
1424 return FALSE;
1425 share = i+1;
1426 for (i = share; i < pathlen; i++)
1427 if (ISSLASH(path[i])) break;
1428 return (i != share && (i == pathlen || i == pathlen-1));
1429
1430 #undef ISSLASH
1431}
1432
1433#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001434static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001435IsUNCRootW(Py_UNICODE *path, int pathlen)
1436{
1437 #define ISSLASH ISSLASHW
1438
1439 int i, share;
1440
1441 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1442 /* minimum UNCRoot is \\x\y */
1443 return FALSE;
1444 for (i = 2; i < pathlen ; i++)
1445 if (ISSLASH(path[i])) break;
1446 if (i == 2 || i == pathlen)
1447 /* do not allow \\\SHARE or \\SERVER */
1448 return FALSE;
1449 share = i+1;
1450 for (i = share; i < pathlen; i++)
1451 if (ISSLASH(path[i])) break;
1452 return (i != share && (i == pathlen || i == pathlen-1));
1453
1454 #undef ISSLASH
1455}
1456#endif /* Py_WIN_WIDE_FILENAMES */
1457#endif /* MS_WINDOWS */
1458
Barry Warsaw53699e91996-12-10 23:23:01 +00001459static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001460posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001461 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001462#ifdef __VMS
1463 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1464#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001465 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001466#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001467 char *wformat,
1468 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001469{
Fred Drake699f3522000-06-29 21:12:41 +00001470 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001471 char *path = NULL; /* pass this to stat; do not free() it */
1472 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001473 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001474 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001475
1476#ifdef Py_WIN_WIDE_FILENAMES
1477 /* If on wide-character-capable OS see if argument
1478 is Unicode and if so use wide API. */
1479 if (unicode_file_names()) {
1480 PyUnicodeObject *po;
1481 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001482 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1483
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001484 Py_BEGIN_ALLOW_THREADS
1485 /* PyUnicode_AS_UNICODE result OK without
1486 thread lock as it is a simple dereference. */
1487 res = wstatfunc(wpath, &st);
1488 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001489
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001490 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001491 return win32_error_unicode("stat", wpath);
1492 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001493 }
1494 /* Drop the argument parsing error as narrow strings
1495 are also valid. */
1496 PyErr_Clear();
1497 }
1498#endif
1499
Tim Peters5aa91602002-01-30 05:46:57 +00001500 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001501 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001502 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001503 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001504
Barry Warsaw53699e91996-12-10 23:23:01 +00001505 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001506 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001507 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001508
1509 if (res != 0) {
1510#ifdef MS_WINDOWS
1511 result = win32_error("stat", pathfree);
1512#else
1513 result = posix_error_with_filename(pathfree);
1514#endif
1515 }
1516 else
1517 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001518
Tim Peters500bd032001-12-19 19:05:01 +00001519 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001520 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001521}
1522
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001523/* POSIX methods */
1524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001525PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001526"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001527Use the real uid/gid to test for access to a path. Note that most\n\
1528operations will use the effective uid/gid, therefore this routine can\n\
1529be used in a suid/sgid environment to test if the invoking user has the\n\
1530specified access to the path. The mode argument can be F_OK to test\n\
1531existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001532
1533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001534posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001535{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001536 char *path;
1537 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001538
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001539#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001540 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001541 if (unicode_file_names()) {
1542 PyUnicodeObject *po;
1543 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1544 Py_BEGIN_ALLOW_THREADS
1545 /* PyUnicode_AS_UNICODE OK without thread lock as
1546 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001547 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001548 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001549 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001550 }
1551 /* Drop the argument parsing error as narrow strings
1552 are also valid. */
1553 PyErr_Clear();
1554 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001555 if (!PyArg_ParseTuple(args, "eti:access",
1556 Py_FileSystemDefaultEncoding, &path, &mode))
1557 return 0;
1558 Py_BEGIN_ALLOW_THREADS
1559 attr = GetFileAttributesA(path);
1560 Py_END_ALLOW_THREADS
1561 PyMem_Free(path);
1562finish:
1563 if (attr == 0xFFFFFFFF)
1564 /* File does not exist, or cannot read attributes */
1565 return PyBool_FromLong(0);
1566 /* Access is possible if either write access wasn't requested, or
Guido van Rossumb00324f2007-12-04 01:13:14 +00001567 the file isn't read-only, or if it's a directory, as there are
1568 no read-only directories on Windows. */
1569 return PyBool_FromLong(!(mode & 2)
1570 || !(attr & FILE_ATTRIBUTE_READONLY)
1571 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001572#else
1573 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001574 if (!PyArg_ParseTuple(args, "eti:access",
1575 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001576 return NULL;
1577 Py_BEGIN_ALLOW_THREADS
1578 res = access(path, mode);
1579 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001580 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001581 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001582#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001583}
1584
Guido van Rossumd371ff11999-01-25 16:12:23 +00001585#ifndef F_OK
1586#define F_OK 0
1587#endif
1588#ifndef R_OK
1589#define R_OK 4
1590#endif
1591#ifndef W_OK
1592#define W_OK 2
1593#endif
1594#ifndef X_OK
1595#define X_OK 1
1596#endif
1597
1598#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001599PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001600"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001601Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001602
1603static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001604posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001605{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001606 int id;
1607 char *ret;
1608
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001609 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001610 return NULL;
1611
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001612#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001613 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001614 if (id == 0) {
1615 ret = ttyname();
1616 }
1617 else {
1618 ret = NULL;
1619 }
1620#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001621 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001622#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001623 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001624 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001625 return PyUnicode_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001626}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001627#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001628
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001629#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001630PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001631"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001632Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001633
1634static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001635posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001636{
1637 char *ret;
1638 char buffer[L_ctermid];
1639
Greg Wardb48bc172000-03-01 21:51:56 +00001640#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001641 ret = ctermid_r(buffer);
1642#else
1643 ret = ctermid(buffer);
1644#endif
1645 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001646 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001647 return PyUnicode_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001648}
1649#endif
1650
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001651PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001652"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001653Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001654
Barry Warsaw53699e91996-12-10 23:23:01 +00001655static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001656posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001657{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001658#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00001659 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001660#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001661 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001662#elif defined(__VMS)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001663 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001664#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001665 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001666#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001667}
1668
Fred Drake4d1e64b2002-04-15 19:40:07 +00001669#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001670PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001671"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001672Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001673opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001674
1675static PyObject *
1676posix_fchdir(PyObject *self, PyObject *fdobj)
1677{
1678 return posix_fildes(fdobj, fchdir);
1679}
1680#endif /* HAVE_FCHDIR */
1681
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001682
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001683PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001684"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001685Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001686
Barry Warsaw53699e91996-12-10 23:23:01 +00001687static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001688posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001689{
Mark Hammondef8b6542001-05-13 08:04:26 +00001690 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001691 int i;
1692 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001693#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001694 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001695 if (unicode_file_names()) {
1696 PyUnicodeObject *po;
1697 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1698 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001699 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1700 if (attr != 0xFFFFFFFF) {
1701 if (i & _S_IWRITE)
1702 attr &= ~FILE_ATTRIBUTE_READONLY;
1703 else
1704 attr |= FILE_ATTRIBUTE_READONLY;
1705 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1706 }
1707 else
1708 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001709 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001710 if (!res)
1711 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001712 PyUnicode_AS_UNICODE(po));
1713 Py_INCREF(Py_None);
1714 return Py_None;
1715 }
1716 /* Drop the argument parsing error as narrow strings
1717 are also valid. */
1718 PyErr_Clear();
1719 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001720 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1721 &path, &i))
1722 return NULL;
1723 Py_BEGIN_ALLOW_THREADS
1724 attr = GetFileAttributesA(path);
1725 if (attr != 0xFFFFFFFF) {
1726 if (i & _S_IWRITE)
1727 attr &= ~FILE_ATTRIBUTE_READONLY;
1728 else
1729 attr |= FILE_ATTRIBUTE_READONLY;
1730 res = SetFileAttributesA(path, attr);
1731 }
1732 else
1733 res = 0;
1734 Py_END_ALLOW_THREADS
1735 if (!res) {
1736 win32_error("chmod", path);
1737 PyMem_Free(path);
1738 return NULL;
1739 }
1740 PyMem_Free(path);
1741 Py_INCREF(Py_None);
1742 return Py_None;
1743#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001744 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001745 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001746 return NULL;
1747 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001748 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001749 Py_END_ALLOW_THREADS
1750 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001751 return posix_error_with_allocated_filename(path);
1752 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001753 Py_INCREF(Py_None);
1754 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001755#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001756}
1757
Christian Heimes4e30a842007-11-30 22:12:06 +00001758#ifdef HAVE_FCHMOD
1759PyDoc_STRVAR(posix_fchmod__doc__,
1760"fchmod(fd, mode)\n\n\
1761Change the access permissions of the file given by file\n\
1762descriptor fd.");
1763
1764static PyObject *
1765posix_fchmod(PyObject *self, PyObject *args)
1766{
1767 int fd, mode, res;
1768 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1769 return NULL;
1770 Py_BEGIN_ALLOW_THREADS
1771 res = fchmod(fd, mode);
1772 Py_END_ALLOW_THREADS
1773 if (res < 0)
1774 return posix_error();
1775 Py_RETURN_NONE;
1776}
1777#endif /* HAVE_FCHMOD */
1778
1779#ifdef HAVE_LCHMOD
1780PyDoc_STRVAR(posix_lchmod__doc__,
1781"lchmod(path, mode)\n\n\
1782Change the access permissions of a file. If path is a symlink, this\n\
1783affects the link itself rather than the target.");
1784
1785static PyObject *
1786posix_lchmod(PyObject *self, PyObject *args)
1787{
1788 char *path = NULL;
1789 int i;
1790 int res;
1791 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1792 &path, &i))
1793 return NULL;
1794 Py_BEGIN_ALLOW_THREADS
1795 res = lchmod(path, i);
1796 Py_END_ALLOW_THREADS
1797 if (res < 0)
1798 return posix_error_with_allocated_filename(path);
1799 PyMem_Free(path);
1800 Py_RETURN_NONE;
1801}
1802#endif /* HAVE_LCHMOD */
1803
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001804
Thomas Wouterscf297e42007-02-23 15:07:44 +00001805#ifdef HAVE_CHFLAGS
1806PyDoc_STRVAR(posix_chflags__doc__,
1807"chflags(path, flags)\n\n\
1808Set file flags.");
1809
1810static PyObject *
1811posix_chflags(PyObject *self, PyObject *args)
1812{
1813 char *path;
1814 unsigned long flags;
1815 int res;
1816 if (!PyArg_ParseTuple(args, "etk:chflags",
1817 Py_FileSystemDefaultEncoding, &path, &flags))
1818 return NULL;
1819 Py_BEGIN_ALLOW_THREADS
1820 res = chflags(path, flags);
1821 Py_END_ALLOW_THREADS
1822 if (res < 0)
1823 return posix_error_with_allocated_filename(path);
1824 PyMem_Free(path);
1825 Py_INCREF(Py_None);
1826 return Py_None;
1827}
1828#endif /* HAVE_CHFLAGS */
1829
1830#ifdef HAVE_LCHFLAGS
1831PyDoc_STRVAR(posix_lchflags__doc__,
1832"lchflags(path, flags)\n\n\
1833Set file flags.\n\
1834This function will not follow symbolic links.");
1835
1836static PyObject *
1837posix_lchflags(PyObject *self, PyObject *args)
1838{
1839 char *path;
1840 unsigned long flags;
1841 int res;
1842 if (!PyArg_ParseTuple(args, "etk:lchflags",
1843 Py_FileSystemDefaultEncoding, &path, &flags))
1844 return NULL;
1845 Py_BEGIN_ALLOW_THREADS
1846 res = lchflags(path, flags);
1847 Py_END_ALLOW_THREADS
1848 if (res < 0)
1849 return posix_error_with_allocated_filename(path);
1850 PyMem_Free(path);
1851 Py_INCREF(Py_None);
1852 return Py_None;
1853}
1854#endif /* HAVE_LCHFLAGS */
1855
Martin v. Löwis244edc82001-10-04 22:44:26 +00001856#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001857PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001858"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001859Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001860
1861static PyObject *
1862posix_chroot(PyObject *self, PyObject *args)
1863{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001864 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001865}
1866#endif
1867
Guido van Rossum21142a01999-01-08 21:05:37 +00001868#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001869PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001870"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001871force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001872
1873static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001874posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001875{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001876 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001877}
1878#endif /* HAVE_FSYNC */
1879
1880#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001881
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001882#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001883extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1884#endif
1885
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001886PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001887"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001888force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001889 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001890
1891static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001892posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001893{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001894 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001895}
1896#endif /* HAVE_FDATASYNC */
1897
1898
Fredrik Lundh10723342000-07-10 16:38:09 +00001899#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001900PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001901"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001902Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001903
Barry Warsaw53699e91996-12-10 23:23:01 +00001904static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001905posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001906{
Mark Hammondef8b6542001-05-13 08:04:26 +00001907 char *path = NULL;
Christian Heimesd5e2b6f2008-03-19 21:50:51 +00001908 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001909 int res;
Christian Heimesd5e2b6f2008-03-19 21:50:51 +00001910 if (!PyArg_ParseTuple(args, "etll:chown",
Tim Peters5aa91602002-01-30 05:46:57 +00001911 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001912 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001913 return NULL;
1914 Py_BEGIN_ALLOW_THREADS
1915 res = chown(path, (uid_t) uid, (gid_t) gid);
1916 Py_END_ALLOW_THREADS
1917 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001918 return posix_error_with_allocated_filename(path);
1919 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001920 Py_INCREF(Py_None);
1921 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001922}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001923#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001924
Christian Heimes4e30a842007-11-30 22:12:06 +00001925#ifdef HAVE_FCHOWN
1926PyDoc_STRVAR(posix_fchown__doc__,
1927"fchown(fd, uid, gid)\n\n\
1928Change the owner and group id of the file given by file descriptor\n\
1929fd to the numeric uid and gid.");
1930
1931static PyObject *
1932posix_fchown(PyObject *self, PyObject *args)
1933{
1934 int fd, uid, gid;
1935 int res;
1936 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
1937 return NULL;
1938 Py_BEGIN_ALLOW_THREADS
1939 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1940 Py_END_ALLOW_THREADS
1941 if (res < 0)
1942 return posix_error();
1943 Py_RETURN_NONE;
1944}
1945#endif /* HAVE_FCHOWN */
1946
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001947#ifdef HAVE_LCHOWN
1948PyDoc_STRVAR(posix_lchown__doc__,
1949"lchown(path, uid, gid)\n\n\
1950Change the owner and group id of path to the numeric uid and gid.\n\
1951This function will not follow symbolic links.");
1952
1953static PyObject *
1954posix_lchown(PyObject *self, PyObject *args)
1955{
1956 char *path = NULL;
1957 int uid, gid;
1958 int res;
1959 if (!PyArg_ParseTuple(args, "etii:lchown",
1960 Py_FileSystemDefaultEncoding, &path,
1961 &uid, &gid))
1962 return NULL;
1963 Py_BEGIN_ALLOW_THREADS
1964 res = lchown(path, (uid_t) uid, (gid_t) gid);
1965 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001966 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001967 return posix_error_with_allocated_filename(path);
1968 PyMem_Free(path);
1969 Py_INCREF(Py_None);
1970 return Py_None;
1971}
1972#endif /* HAVE_LCHOWN */
1973
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001974
Guido van Rossum36bc6801995-06-14 22:54:23 +00001975#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00001976static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00001977posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001978{
1979 char buf[1026];
1980 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001981
1982#ifdef Py_WIN_WIDE_FILENAMES
Guido van Rossumf0af3e32008-10-02 18:55:37 +00001983 if (!use_bytes && unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001984 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001985 wchar_t *wbuf2 = wbuf;
1986 PyObject *resobj;
Guido van Rossumf0af3e32008-10-02 18:55:37 +00001987 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001988 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001989 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
1990 /* If the buffer is large enough, len does not include the
1991 terminating \0. If the buffer is too small, len includes
1992 the space needed for the terminator. */
1993 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
1994 wbuf2 = malloc(len * sizeof(wchar_t));
1995 if (wbuf2)
1996 len = GetCurrentDirectoryW(len, wbuf2);
1997 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001998 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001999 if (!wbuf2) {
2000 PyErr_NoMemory();
2001 return NULL;
2002 }
2003 if (!len) {
2004 if (wbuf2 != wbuf) free(wbuf2);
2005 return win32_error("getcwdu", NULL);
2006 }
2007 resobj = PyUnicode_FromWideChar(wbuf2, len);
2008 if (wbuf2 != wbuf) free(wbuf2);
2009 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002010 }
2011#endif
2012
2013 Py_BEGIN_ALLOW_THREADS
2014#if defined(PYOS_OS2) && defined(PYCC_GCC)
2015 res = _getcwd2(buf, sizeof buf);
2016#else
2017 res = getcwd(buf, sizeof buf);
2018#endif
2019 Py_END_ALLOW_THREADS
2020 if (res == NULL)
2021 return posix_error();
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002022 if (use_bytes)
2023 return PyBytes_FromStringAndSize(buf, strlen(buf));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002024 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2025}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002026
2027PyDoc_STRVAR(posix_getcwd__doc__,
2028"getcwd() -> path\n\n\
2029Return a unicode string representing the current working directory.");
2030
2031static PyObject *
2032posix_getcwd_unicode(PyObject *self)
2033{
2034 return posix_getcwd(0);
2035}
2036
2037PyDoc_STRVAR(posix_getcwdb__doc__,
2038"getcwdb() -> path\n\n\
2039Return a bytes string representing the current working directory.");
2040
2041static PyObject *
2042posix_getcwd_bytes(PyObject *self)
2043{
2044 return posix_getcwd(1);
2045}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002046#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002048
Guido van Rossumb6775db1994-08-01 11:34:53 +00002049#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002050PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002051"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002052Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002053
Barry Warsaw53699e91996-12-10 23:23:01 +00002054static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002055posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002056{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002057 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002058}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002059#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002060
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002061
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002062PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002063"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002064Return a list containing the names of the entries in the directory.\n\
2065\n\
2066 path: path of directory to list\n\
2067\n\
2068The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002069entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002070
Barry Warsaw53699e91996-12-10 23:23:01 +00002071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002072posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002073{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002074 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002075 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002076#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002077
Barry Warsaw53699e91996-12-10 23:23:01 +00002078 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002079 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002080 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002081 WIN32_FIND_DATA FileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002082 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002083 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002084 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002085
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002086#ifdef Py_WIN_WIDE_FILENAMES
2087 /* If on wide-character-capable OS see if argument
2088 is Unicode and if so use wide API. */
2089 if (unicode_file_names()) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002090 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002091 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2092 WIN32_FIND_DATAW wFileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002093 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002094 Py_UNICODE wch;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002095 /* Overallocate for \\*.*\0 */
2096 len = PyUnicode_GET_SIZE(po);
2097 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2098 if (!wnamebuf) {
2099 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002100 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002101 }
2102 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2103 wch = len > 0 ? wnamebuf[len-1] : '\0';
2104 if (wch != L'/' && wch != L'\\' && wch != L':')
2105 wnamebuf[len++] = L'\\';
2106 wcscpy(wnamebuf + len, L"*.*");
2107 if ((d = PyList_New(0)) == NULL) {
2108 free(wnamebuf);
2109 return NULL;
2110 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002111 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2112 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002113 int error = GetLastError();
2114 if (error == ERROR_FILE_NOT_FOUND) {
2115 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002116 return d;
2117 }
2118 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002119 win32_error_unicode("FindFirstFileW", wnamebuf);
2120 free(wnamebuf);
2121 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002122 }
2123 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002124 /* Skip over . and .. */
2125 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2126 wcscmp(wFileData.cFileName, L"..") != 0) {
2127 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2128 if (v == NULL) {
2129 Py_DECREF(d);
2130 d = NULL;
2131 break;
2132 }
2133 if (PyList_Append(d, v) != 0) {
2134 Py_DECREF(v);
2135 Py_DECREF(d);
2136 d = NULL;
2137 break;
2138 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002139 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002140 }
Georg Brandl622927b2006-03-07 12:48:03 +00002141 Py_BEGIN_ALLOW_THREADS
2142 result = FindNextFileW(hFindFile, &wFileData);
2143 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002144 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2145 it got to the end of the directory. */
2146 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2147 Py_DECREF(d);
2148 win32_error_unicode("FindNextFileW", wnamebuf);
2149 FindClose(hFindFile);
2150 free(wnamebuf);
2151 return NULL;
2152 }
Georg Brandl622927b2006-03-07 12:48:03 +00002153 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002154
2155 if (FindClose(hFindFile) == FALSE) {
2156 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002157 win32_error_unicode("FindClose", wnamebuf);
2158 free(wnamebuf);
2159 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002160 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002161 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002162 return d;
2163 }
2164 /* Drop the argument parsing error as narrow strings
2165 are also valid. */
2166 PyErr_Clear();
2167 }
2168#endif
2169
Tim Peters5aa91602002-01-30 05:46:57 +00002170 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002171 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002172 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002173 if (len > 0) {
2174 char ch = namebuf[len-1];
2175 if (ch != SEP && ch != ALTSEP && ch != ':')
2176 namebuf[len++] = '/';
2177 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002178 strcpy(namebuf + len, "*.*");
2179
Barry Warsaw53699e91996-12-10 23:23:01 +00002180 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002181 return NULL;
2182
2183 hFindFile = FindFirstFile(namebuf, &FileData);
2184 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002185 int error = GetLastError();
2186 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002187 return d;
2188 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002189 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002190 }
2191 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002192 /* Skip over . and .. */
2193 if (strcmp(FileData.cFileName, ".") != 0 &&
2194 strcmp(FileData.cFileName, "..") != 0) {
Christian Heimes72b710a2008-05-26 13:28:38 +00002195 v = PyBytes_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002196 if (v == NULL) {
2197 Py_DECREF(d);
2198 d = NULL;
2199 break;
2200 }
2201 if (PyList_Append(d, v) != 0) {
2202 Py_DECREF(v);
2203 Py_DECREF(d);
2204 d = NULL;
2205 break;
2206 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002207 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002208 }
Georg Brandl622927b2006-03-07 12:48:03 +00002209 Py_BEGIN_ALLOW_THREADS
2210 result = FindNextFile(hFindFile, &FileData);
2211 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002212 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2213 it got to the end of the directory. */
2214 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2215 Py_DECREF(d);
2216 win32_error("FindNextFile", namebuf);
2217 FindClose(hFindFile);
2218 return NULL;
2219 }
Georg Brandl622927b2006-03-07 12:48:03 +00002220 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002221
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002222 if (FindClose(hFindFile) == FALSE) {
2223 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002224 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002225 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002226
2227 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002228
Tim Peters0bb44a42000-09-15 07:44:49 +00002229#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002230
2231#ifndef MAX_PATH
2232#define MAX_PATH CCHMAXPATH
2233#endif
2234 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002235 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002236 PyObject *d, *v;
2237 char namebuf[MAX_PATH+5];
2238 HDIR hdir = 1;
2239 ULONG srchcnt = 1;
2240 FILEFINDBUF3 ep;
2241 APIRET rc;
2242
Alexandre Vassalotti70a23712007-10-14 02:05:51 +00002243 if (!PyArg_ParseTuple(args, "et#:listdir",
2244 Py_FileSystemDefaultEncoding, &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002245 return NULL;
2246 if (len >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00002247 PyMem_Free(name);
2248 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002249 return NULL;
2250 }
2251 strcpy(namebuf, name);
2252 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002253 if (*pt == ALTSEP)
2254 *pt = SEP;
2255 if (namebuf[len-1] != SEP)
2256 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002257 strcpy(namebuf + len, "*.*");
2258
Neal Norwitz6c913782007-10-14 03:23:09 +00002259 if ((d = PyList_New(0)) == NULL) {
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002260 PyMem_Free(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002261 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002262 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002263
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002264 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2265 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002266 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002267 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2268 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2269 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002270
2271 if (rc != NO_ERROR) {
2272 errno = ENOENT;
Neal Norwitz6c913782007-10-14 03:23:09 +00002273 return posix_error_with_allocated_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002274 }
2275
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002276 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002277 do {
2278 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002279 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002280 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002281
2282 strcpy(namebuf, ep.achName);
2283
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002284 /* Leave Case of Name Alone -- In Native Form */
2285 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002286
Christian Heimes72b710a2008-05-26 13:28:38 +00002287 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002288 if (v == NULL) {
2289 Py_DECREF(d);
2290 d = NULL;
2291 break;
2292 }
2293 if (PyList_Append(d, v) != 0) {
2294 Py_DECREF(v);
2295 Py_DECREF(d);
2296 d = NULL;
2297 break;
2298 }
2299 Py_DECREF(v);
2300 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2301 }
2302
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002303 PyMem_Free(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002304 return d;
2305#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002306
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002307 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002308 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002309 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002310 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002311 int arg_is_unicode = 1;
2312
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002313 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002314 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2315 arg_is_unicode = 0;
2316 PyErr_Clear();
2317 }
2318 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002319 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002320 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002321 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002322 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002323 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002324 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002325 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002326 return NULL;
2327 }
Georg Brandl622927b2006-03-07 12:48:03 +00002328 for (;;) {
Georg Brandl3dbca812008-07-23 16:10:53 +00002329 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002330 Py_BEGIN_ALLOW_THREADS
2331 ep = readdir(dirp);
2332 Py_END_ALLOW_THREADS
Georg Brandl3dbca812008-07-23 16:10:53 +00002333 if (ep == NULL) {
2334 if (errno == 0) {
2335 break;
2336 } else {
2337 closedir(dirp);
2338 Py_DECREF(d);
2339 return posix_error_with_allocated_filename(name);
2340 }
2341 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002342 if (ep->d_name[0] == '.' &&
2343 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002344 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002345 continue;
Christian Heimes72b710a2008-05-26 13:28:38 +00002346 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002347 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002348 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002349 d = NULL;
2350 break;
2351 }
Just van Rossum96b1c902003-03-03 17:32:15 +00002352 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002353 PyObject *w;
2354
2355 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002356 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002357 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002358 if (w != NULL) {
2359 Py_DECREF(v);
2360 v = w;
2361 }
2362 else {
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002363 /* Ignore undecodable filenames, as discussed
2364 * in issue 3187. To include these,
2365 * use getcwdb(). */
Just van Rossum6a421832003-03-04 19:30:44 +00002366 PyErr_Clear();
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002367 Py_DECREF(v);
2368 continue;
Just van Rossum46c97842003-02-25 21:42:15 +00002369 }
Just van Rossum46c97842003-02-25 21:42:15 +00002370 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002371 if (PyList_Append(d, v) != 0) {
2372 Py_DECREF(v);
2373 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002374 d = NULL;
2375 break;
2376 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002377 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002378 }
2379 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002380 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002381
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002382 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002383
Tim Peters0bb44a42000-09-15 07:44:49 +00002384#endif /* which OS */
2385} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002386
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002387#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002388/* A helper function for abspath on win32 */
2389static PyObject *
2390posix__getfullpathname(PyObject *self, PyObject *args)
2391{
2392 /* assume encoded strings wont more than double no of chars */
2393 char inbuf[MAX_PATH*2];
2394 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002395 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002396 char outbuf[MAX_PATH*2];
2397 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002398#ifdef Py_WIN_WIDE_FILENAMES
2399 if (unicode_file_names()) {
2400 PyUnicodeObject *po;
2401 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2402 Py_UNICODE woutbuf[MAX_PATH*2];
2403 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002404 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002405 sizeof(woutbuf)/sizeof(woutbuf[0]),
2406 woutbuf, &wtemp))
2407 return win32_error("GetFullPathName", "");
2408 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2409 }
2410 /* Drop the argument parsing error as narrow strings
2411 are also valid. */
2412 PyErr_Clear();
2413 }
2414#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002415 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2416 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002417 &insize))
2418 return NULL;
2419 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2420 outbuf, &temp))
2421 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002422 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2423 return PyUnicode_Decode(outbuf, strlen(outbuf),
2424 Py_FileSystemDefaultEncoding, NULL);
2425 }
Christian Heimes72b710a2008-05-26 13:28:38 +00002426 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002427} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002428#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002429
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002430PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002431"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002432Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002433
Barry Warsaw53699e91996-12-10 23:23:01 +00002434static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002435posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002436{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002437 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002438 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002439 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002440
2441#ifdef Py_WIN_WIDE_FILENAMES
2442 if (unicode_file_names()) {
2443 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002444 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002445 Py_BEGIN_ALLOW_THREADS
2446 /* PyUnicode_AS_UNICODE OK without thread lock as
2447 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002448 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002449 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002450 if (!res)
2451 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002452 Py_INCREF(Py_None);
2453 return Py_None;
2454 }
2455 /* Drop the argument parsing error as narrow strings
2456 are also valid. */
2457 PyErr_Clear();
2458 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002459 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2460 Py_FileSystemDefaultEncoding, &path, &mode))
2461 return NULL;
2462 Py_BEGIN_ALLOW_THREADS
2463 /* PyUnicode_AS_UNICODE OK without thread lock as
2464 it is a simple dereference. */
2465 res = CreateDirectoryA(path, NULL);
2466 Py_END_ALLOW_THREADS
2467 if (!res) {
2468 win32_error("mkdir", path);
2469 PyMem_Free(path);
2470 return NULL;
2471 }
2472 PyMem_Free(path);
2473 Py_INCREF(Py_None);
2474 return Py_None;
2475#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002476
Tim Peters5aa91602002-01-30 05:46:57 +00002477 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002478 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002479 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002480 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002481#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002482 res = mkdir(path);
2483#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002484 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002485#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002486 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002487 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002488 return posix_error_with_allocated_filename(path);
2489 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002490 Py_INCREF(Py_None);
2491 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002492#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002493}
2494
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002495
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002496/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2497#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002498#include <sys/resource.h>
2499#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002500
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002501
2502#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002503PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002504"nice(inc) -> new_priority\n\n\
2505Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002506
Barry Warsaw53699e91996-12-10 23:23:01 +00002507static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002508posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002509{
2510 int increment, value;
2511
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002512 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002513 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002514
2515 /* There are two flavours of 'nice': one that returns the new
2516 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002517 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2518 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002519
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002520 If we are of the nice family that returns the new priority, we
2521 need to clear errno before the call, and check if errno is filled
2522 before calling posix_error() on a returnvalue of -1, because the
2523 -1 may be the actual new priority! */
2524
2525 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002526 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002527#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002528 if (value == 0)
2529 value = getpriority(PRIO_PROCESS, 0);
2530#endif
2531 if (value == -1 && errno != 0)
2532 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002533 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00002534 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002535}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002536#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002537
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002538PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002539"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002540Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002541
Barry Warsaw53699e91996-12-10 23:23:01 +00002542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002543posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002544{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002545#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002546 PyObject *o1, *o2;
2547 char *p1, *p2;
2548 BOOL result;
2549 if (unicode_file_names()) {
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002550 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2551 goto error;
2552 if (!convert_to_unicode(&o1))
2553 goto error;
2554 if (!convert_to_unicode(&o2)) {
2555 Py_DECREF(o1);
2556 goto error;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002557 }
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002558 Py_BEGIN_ALLOW_THREADS
2559 result = MoveFileW(PyUnicode_AsUnicode(o1),
2560 PyUnicode_AsUnicode(o2));
2561 Py_END_ALLOW_THREADS
2562 Py_DECREF(o1);
2563 Py_DECREF(o2);
2564 if (!result)
2565 return win32_error("rename", NULL);
2566 Py_INCREF(Py_None);
2567 return Py_None;
2568error:
2569 PyErr_Clear();
Thomas Wouters477c8d52006-05-27 19:21:47 +00002570 }
2571 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2572 return NULL;
2573 Py_BEGIN_ALLOW_THREADS
2574 result = MoveFileA(p1, p2);
2575 Py_END_ALLOW_THREADS
2576 if (!result)
2577 return win32_error("rename", NULL);
2578 Py_INCREF(Py_None);
2579 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002580#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002581 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002582#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002583}
2584
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002585
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002586PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002587"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002588Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002589
Barry Warsaw53699e91996-12-10 23:23:01 +00002590static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002591posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002592{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002593#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00002594 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002595#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002596 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002597#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002598}
2599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002601PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002602"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002603Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002604
Barry Warsaw53699e91996-12-10 23:23:01 +00002605static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002606posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002607{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002608#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002609 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002610#else
2611 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2612#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002613}
2614
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002615
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002616#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002617PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002618"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002619Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002620
Barry Warsaw53699e91996-12-10 23:23:01 +00002621static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002622posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002623{
Guido van Rossumff4949e1992-08-05 19:58:53 +00002624 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002625#ifdef MS_WINDOWS
2626 wchar_t *command;
2627 if (!PyArg_ParseTuple(args, "u:system", &command))
2628 return NULL;
2629#else
2630 char *command;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002631 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002632 return NULL;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002633#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002634 Py_BEGIN_ALLOW_THREADS
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002635#ifdef MS_WINDOWS
2636 sts = _wsystem(command);
2637#else
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002638 sts = system(command);
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002639#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002640 Py_END_ALLOW_THREADS
Christian Heimes217cfd12007-12-02 14:31:20 +00002641 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002642}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002643#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002644
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002645
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002646PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002647"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002648Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002649
Barry Warsaw53699e91996-12-10 23:23:01 +00002650static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002651posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002652{
2653 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002654 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002655 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002656 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002657 if (i < 0)
2658 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00002659 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002660}
2661
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002662
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002663PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002664"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002665Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002666
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002667PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002668"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002669Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002670
Barry Warsaw53699e91996-12-10 23:23:01 +00002671static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002672posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002673{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002674#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00002675 return win32_1str(args, "remove", "y:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002676#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002677 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002678#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002679}
2680
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002681
Guido van Rossumb6775db1994-08-01 11:34:53 +00002682#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002683PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002684"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002685Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002686
Barry Warsaw53699e91996-12-10 23:23:01 +00002687static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002688posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002689{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002690 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002691 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002692
Barry Warsaw53699e91996-12-10 23:23:01 +00002693 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002694 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002695 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002696 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002697 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002698 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002699 u.sysname,
2700 u.nodename,
2701 u.release,
2702 u.version,
2703 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002704}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002705#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002706
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002707static int
2708extract_time(PyObject *t, long* sec, long* usec)
2709{
2710 long intval;
2711 if (PyFloat_Check(t)) {
2712 double tval = PyFloat_AsDouble(t);
Christian Heimes90aa7642007-12-19 02:45:37 +00002713 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002714 if (!intobj)
2715 return -1;
Christian Heimes217cfd12007-12-02 14:31:20 +00002716 intval = PyLong_AsLong(intobj);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002717 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002718 if (intval == -1 && PyErr_Occurred())
2719 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002720 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002721 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002722 if (*usec < 0)
2723 /* If rounding gave us a negative number,
2724 truncate. */
2725 *usec = 0;
2726 return 0;
2727 }
Christian Heimes217cfd12007-12-02 14:31:20 +00002728 intval = PyLong_AsLong(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002729 if (intval == -1 && PyErr_Occurred())
2730 return -1;
2731 *sec = intval;
2732 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002733 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002734}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002735
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002736PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002737"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002738utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002739Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002740second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002741
Barry Warsaw53699e91996-12-10 23:23:01 +00002742static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002743posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002744{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002745#ifdef Py_WIN_WIDE_FILENAMES
2746 PyObject *arg;
2747 PyUnicodeObject *obwpath;
2748 wchar_t *wpath = NULL;
2749 char *apath = NULL;
2750 HANDLE hFile;
2751 long atimesec, mtimesec, ausec, musec;
2752 FILETIME atime, mtime;
2753 PyObject *result = NULL;
2754
2755 if (unicode_file_names()) {
2756 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2757 wpath = PyUnicode_AS_UNICODE(obwpath);
2758 Py_BEGIN_ALLOW_THREADS
2759 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002760 NULL, OPEN_EXISTING,
2761 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002762 Py_END_ALLOW_THREADS
2763 if (hFile == INVALID_HANDLE_VALUE)
2764 return win32_error_unicode("utime", wpath);
2765 } else
2766 /* Drop the argument parsing error as narrow strings
2767 are also valid. */
2768 PyErr_Clear();
2769 }
2770 if (!wpath) {
2771 if (!PyArg_ParseTuple(args, "etO:utime",
2772 Py_FileSystemDefaultEncoding, &apath, &arg))
2773 return NULL;
2774 Py_BEGIN_ALLOW_THREADS
2775 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002776 NULL, OPEN_EXISTING,
2777 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002778 Py_END_ALLOW_THREADS
2779 if (hFile == INVALID_HANDLE_VALUE) {
2780 win32_error("utime", apath);
2781 PyMem_Free(apath);
2782 return NULL;
2783 }
2784 PyMem_Free(apath);
2785 }
2786
2787 if (arg == Py_None) {
2788 SYSTEMTIME now;
2789 GetSystemTime(&now);
2790 if (!SystemTimeToFileTime(&now, &mtime) ||
2791 !SystemTimeToFileTime(&now, &atime)) {
2792 win32_error("utime", NULL);
2793 goto done;
2794 }
2795 }
2796 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2797 PyErr_SetString(PyExc_TypeError,
2798 "utime() arg 2 must be a tuple (atime, mtime)");
2799 goto done;
2800 }
2801 else {
2802 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2803 &atimesec, &ausec) == -1)
2804 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002805 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002806 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2807 &mtimesec, &musec) == -1)
2808 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002809 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002810 }
2811 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2812 /* Avoid putting the file name into the error here,
2813 as that may confuse the user into believing that
2814 something is wrong with the file, when it also
2815 could be the time stamp that gives a problem. */
2816 win32_error("utime", NULL);
2817 }
2818 Py_INCREF(Py_None);
2819 result = Py_None;
2820done:
2821 CloseHandle(hFile);
2822 return result;
2823#else /* Py_WIN_WIDE_FILENAMES */
2824
Neal Norwitz2adf2102004-06-09 01:46:02 +00002825 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002826 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002827 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002828 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002829
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002830#if defined(HAVE_UTIMES)
2831 struct timeval buf[2];
2832#define ATIME buf[0].tv_sec
2833#define MTIME buf[1].tv_sec
2834#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002835/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002836 struct utimbuf buf;
2837#define ATIME buf.actime
2838#define MTIME buf.modtime
2839#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002840#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002841 time_t buf[2];
2842#define ATIME buf[0]
2843#define MTIME buf[1]
2844#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002845#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002846
Mark Hammond817c9292003-12-03 01:22:38 +00002847
Thomas Wouters477c8d52006-05-27 19:21:47 +00002848 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002849 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002850 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002851 if (arg == Py_None) {
2852 /* optional time values not given */
2853 Py_BEGIN_ALLOW_THREADS
2854 res = utime(path, NULL);
2855 Py_END_ALLOW_THREADS
2856 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002857 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002858 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002859 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002860 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002861 return NULL;
2862 }
2863 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002864 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002865 &atime, &ausec) == -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 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002869 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002870 &mtime, &musec) == -1) {
2871 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002872 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002873 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002874 ATIME = atime;
2875 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002876#ifdef HAVE_UTIMES
2877 buf[0].tv_usec = ausec;
2878 buf[1].tv_usec = musec;
2879 Py_BEGIN_ALLOW_THREADS
2880 res = utimes(path, buf);
2881 Py_END_ALLOW_THREADS
2882#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002883 Py_BEGIN_ALLOW_THREADS
2884 res = utime(path, UTIME_ARG);
2885 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002886#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002887 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002888 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002889 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002890 }
Neal Norwitz96652712004-06-06 20:40:27 +00002891 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002892 Py_INCREF(Py_None);
2893 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002894#undef UTIME_ARG
2895#undef ATIME
2896#undef MTIME
Thomas Wouters477c8d52006-05-27 19:21:47 +00002897#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002898}
2899
Guido van Rossum85e3b011991-06-03 12:42:10 +00002900
Guido van Rossum3b066191991-06-04 19:40:25 +00002901/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002902
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002903PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002904"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002905Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002906
Barry Warsaw53699e91996-12-10 23:23:01 +00002907static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002908posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002909{
2910 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002911 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002912 return NULL;
2913 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002914 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002915}
2916
Martin v. Löwis114619e2002-10-07 06:44:21 +00002917#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2918static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002919free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002920{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002921 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002922 for (i = 0; i < count; i++)
2923 PyMem_Free(array[i]);
2924 PyMem_DEL(array);
2925}
2926#endif
2927
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002928
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002929#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002930PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002931"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002932Execute an executable path with arguments, replacing current process.\n\
2933\n\
2934 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002935 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002936
Barry Warsaw53699e91996-12-10 23:23:01 +00002937static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002938posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002939{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002940 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002941 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002942 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002943 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002944 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002945
Guido van Rossum89b33251993-10-22 14:26:06 +00002946 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002947 argv is a list or tuple of strings. */
2948
Martin v. Löwis114619e2002-10-07 06:44:21 +00002949 if (!PyArg_ParseTuple(args, "etO:execv",
2950 Py_FileSystemDefaultEncoding,
2951 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002952 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002953 if (PyList_Check(argv)) {
2954 argc = PyList_Size(argv);
2955 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002956 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002957 else if (PyTuple_Check(argv)) {
2958 argc = PyTuple_Size(argv);
2959 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002960 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002961 else {
Fred Drake661ea262000-10-24 19:57:45 +00002962 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002963 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002964 return NULL;
2965 }
Thomas Heller6790d602007-08-30 17:15:14 +00002966 if (argc < 1) {
2967 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
2968 PyMem_Free(path);
2969 return NULL;
2970 }
Guido van Rossum50422b42000-04-26 20:34:28 +00002971
Barry Warsaw53699e91996-12-10 23:23:01 +00002972 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002973 if (argvlist == NULL) {
2974 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002975 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002976 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002977 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002978 if (!PyArg_Parse((*getitem)(argv, i), "et",
2979 Py_FileSystemDefaultEncoding,
2980 &argvlist[i])) {
2981 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002982 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002983 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002984 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002985 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002986
Guido van Rossum85e3b011991-06-03 12:42:10 +00002987 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002988 }
2989 argvlist[argc] = NULL;
2990
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002991 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002992
Guido van Rossum85e3b011991-06-03 12:42:10 +00002993 /* If we get here it's definitely an error */
2994
Martin v. Löwis114619e2002-10-07 06:44:21 +00002995 free_string_array(argvlist, argc);
2996 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002997 return posix_error();
2998}
2999
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003000
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003001PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003002"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003003Execute a path with arguments and environment, replacing current process.\n\
3004\n\
3005 path: path of executable file\n\
3006 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003007 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003008
Barry Warsaw53699e91996-12-10 23:23:01 +00003009static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003010posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003011{
3012 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003013 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003014 char **argvlist;
3015 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003016 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003017 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003018 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003019 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003020
3021 /* execve has three arguments: (path, argv, env), where
3022 argv is a list or tuple of strings and env is a dictionary
3023 like posix.environ. */
3024
Martin v. Löwis114619e2002-10-07 06:44:21 +00003025 if (!PyArg_ParseTuple(args, "etOO:execve",
3026 Py_FileSystemDefaultEncoding,
3027 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003028 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003029 if (PyList_Check(argv)) {
3030 argc = PyList_Size(argv);
3031 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003032 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003033 else if (PyTuple_Check(argv)) {
3034 argc = PyTuple_Size(argv);
3035 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003036 }
3037 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003038 PyErr_SetString(PyExc_TypeError,
3039 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003040 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003041 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003042 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003043 PyErr_SetString(PyExc_TypeError,
3044 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003045 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003046 }
3047
Barry Warsaw53699e91996-12-10 23:23:01 +00003048 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003049 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003050 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003051 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003052 }
3053 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003054 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003055 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003056 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003057 &argvlist[i]))
3058 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003059 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003060 goto fail_1;
3061 }
3062 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003063 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003064 argvlist[argc] = NULL;
3065
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003066 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003067 if (i < 0)
3068 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003069 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003070 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003071 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003072 goto fail_1;
3073 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003074 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003075 keys = PyMapping_Keys(env);
3076 vals = PyMapping_Values(env);
3077 if (!keys || !vals)
3078 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003079 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3080 PyErr_SetString(PyExc_TypeError,
3081 "execve(): env.keys() or env.values() is not a list");
3082 goto fail_2;
3083 }
Tim Peters5aa91602002-01-30 05:46:57 +00003084
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003085 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003086 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003087 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003088
3089 key = PyList_GetItem(keys, pos);
3090 val = PyList_GetItem(vals, pos);
3091 if (!key || !val)
3092 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003093
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003094 if (!PyArg_Parse(
3095 key,
3096 "s;execve() arg 3 contains a non-string key",
3097 &k) ||
3098 !PyArg_Parse(
3099 val,
3100 "s;execve() arg 3 contains a non-string value",
3101 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003102 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003103 goto fail_2;
3104 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003105
3106#if defined(PYOS_OS2)
3107 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3108 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3109#endif
Christian Heimes830a4bc2007-11-22 07:43:40 +00003110 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003111 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003112 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003113 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003114 goto fail_2;
3115 }
Tim Petersc8996f52001-12-03 20:41:00 +00003116 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003117 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003118#if defined(PYOS_OS2)
3119 }
3120#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003121 }
3122 envlist[envc] = 0;
3123
3124 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003125
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003126 /* If we get here it's definitely an error */
3127
3128 (void) posix_error();
3129
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003130 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003131 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003132 PyMem_DEL(envlist[envc]);
3133 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003134 fail_1:
3135 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003136 Py_XDECREF(vals);
3137 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003138 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003139 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003140 return NULL;
3141}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003142#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003143
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003144
Guido van Rossuma1065681999-01-25 23:20:23 +00003145#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003146PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003147"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003148Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003149\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003150 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003151 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003152 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003153
3154static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003155posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003156{
3157 char *path;
3158 PyObject *argv;
3159 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003160 int mode, i;
3161 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003162 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003163 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003164
3165 /* spawnv has three arguments: (mode, path, argv), where
3166 argv is a list or tuple of strings. */
3167
Martin v. Löwis114619e2002-10-07 06:44:21 +00003168 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3169 Py_FileSystemDefaultEncoding,
3170 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003171 return NULL;
3172 if (PyList_Check(argv)) {
3173 argc = PyList_Size(argv);
3174 getitem = PyList_GetItem;
3175 }
3176 else if (PyTuple_Check(argv)) {
3177 argc = PyTuple_Size(argv);
3178 getitem = PyTuple_GetItem;
3179 }
3180 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003181 PyErr_SetString(PyExc_TypeError,
3182 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003183 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003184 return NULL;
3185 }
3186
3187 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003188 if (argvlist == NULL) {
3189 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003190 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003191 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003192 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003193 if (!PyArg_Parse((*getitem)(argv, i), "et",
3194 Py_FileSystemDefaultEncoding,
3195 &argvlist[i])) {
3196 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003197 PyErr_SetString(
3198 PyExc_TypeError,
3199 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003200 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003201 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003202 }
3203 }
3204 argvlist[argc] = NULL;
3205
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003206#if defined(PYOS_OS2) && defined(PYCC_GCC)
3207 Py_BEGIN_ALLOW_THREADS
3208 spawnval = spawnv(mode, path, argvlist);
3209 Py_END_ALLOW_THREADS
3210#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003211 if (mode == _OLD_P_OVERLAY)
3212 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003213
Tim Peters25059d32001-12-07 20:35:43 +00003214 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003215 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003216 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003217#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003218
Martin v. Löwis114619e2002-10-07 06:44:21 +00003219 free_string_array(argvlist, argc);
3220 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003221
Fred Drake699f3522000-06-29 21:12:41 +00003222 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003223 return posix_error();
3224 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003225#if SIZEOF_LONG == SIZEOF_VOID_P
3226 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003227#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003228 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003229#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003230}
3231
3232
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003233PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003234"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003235Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003236\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003237 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003238 path: path of executable file\n\
3239 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003240 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003241
3242static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003243posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003244{
3245 char *path;
3246 PyObject *argv, *env;
3247 char **argvlist;
3248 char **envlist;
3249 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003250 int mode, pos, envc;
3251 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003252 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003253 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003254 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003255
3256 /* spawnve has four arguments: (mode, path, argv, env), where
3257 argv is a list or tuple of strings and env is a dictionary
3258 like posix.environ. */
3259
Martin v. Löwis114619e2002-10-07 06:44:21 +00003260 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3261 Py_FileSystemDefaultEncoding,
3262 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003263 return NULL;
3264 if (PyList_Check(argv)) {
3265 argc = PyList_Size(argv);
3266 getitem = PyList_GetItem;
3267 }
3268 else if (PyTuple_Check(argv)) {
3269 argc = PyTuple_Size(argv);
3270 getitem = PyTuple_GetItem;
3271 }
3272 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003273 PyErr_SetString(PyExc_TypeError,
3274 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003275 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003276 }
3277 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003278 PyErr_SetString(PyExc_TypeError,
3279 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003280 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003281 }
3282
3283 argvlist = PyMem_NEW(char *, argc+1);
3284 if (argvlist == NULL) {
3285 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003286 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003287 }
3288 for (i = 0; i < argc; i++) {
3289 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003290 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003291 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003292 &argvlist[i]))
3293 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003294 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003295 goto fail_1;
3296 }
3297 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003298 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003299 argvlist[argc] = NULL;
3300
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003301 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003302 if (i < 0)
3303 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003304 envlist = PyMem_NEW(char *, i + 1);
3305 if (envlist == NULL) {
3306 PyErr_NoMemory();
3307 goto fail_1;
3308 }
3309 envc = 0;
3310 keys = PyMapping_Keys(env);
3311 vals = PyMapping_Values(env);
3312 if (!keys || !vals)
3313 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003314 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3315 PyErr_SetString(PyExc_TypeError,
3316 "spawnve(): env.keys() or env.values() is not a list");
3317 goto fail_2;
3318 }
Tim Peters5aa91602002-01-30 05:46:57 +00003319
Guido van Rossuma1065681999-01-25 23:20:23 +00003320 for (pos = 0; pos < i; pos++) {
3321 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003322 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003323
3324 key = PyList_GetItem(keys, pos);
3325 val = PyList_GetItem(vals, pos);
3326 if (!key || !val)
3327 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003328
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003329 if (!PyArg_Parse(
3330 key,
3331 "s;spawnve() arg 3 contains a non-string key",
3332 &k) ||
3333 !PyArg_Parse(
3334 val,
3335 "s;spawnve() arg 3 contains a non-string value",
3336 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003337 {
3338 goto fail_2;
3339 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003340 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003341 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003342 if (p == NULL) {
3343 PyErr_NoMemory();
3344 goto fail_2;
3345 }
Tim Petersc8996f52001-12-03 20:41:00 +00003346 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003347 envlist[envc++] = p;
3348 }
3349 envlist[envc] = 0;
3350
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003351#if defined(PYOS_OS2) && defined(PYCC_GCC)
3352 Py_BEGIN_ALLOW_THREADS
3353 spawnval = spawnve(mode, path, argvlist, envlist);
3354 Py_END_ALLOW_THREADS
3355#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003356 if (mode == _OLD_P_OVERLAY)
3357 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003358
3359 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003360 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003361 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003362#endif
Tim Peters25059d32001-12-07 20:35:43 +00003363
Fred Drake699f3522000-06-29 21:12:41 +00003364 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003365 (void) posix_error();
3366 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003367#if SIZEOF_LONG == SIZEOF_VOID_P
3368 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003369#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003370 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003371#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003372
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003373 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003374 while (--envc >= 0)
3375 PyMem_DEL(envlist[envc]);
3376 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003377 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003378 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003379 Py_XDECREF(vals);
3380 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003381 fail_0:
3382 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003383 return res;
3384}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003385
3386/* OS/2 supports spawnvp & spawnvpe natively */
3387#if defined(PYOS_OS2)
3388PyDoc_STRVAR(posix_spawnvp__doc__,
3389"spawnvp(mode, file, args)\n\n\
3390Execute the program 'file' in a new process, using the environment\n\
3391search path to find the file.\n\
3392\n\
3393 mode: mode of process creation\n\
3394 file: executable file name\n\
3395 args: tuple or list of strings");
3396
3397static PyObject *
3398posix_spawnvp(PyObject *self, PyObject *args)
3399{
3400 char *path;
3401 PyObject *argv;
3402 char **argvlist;
3403 int mode, i, argc;
3404 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003405 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003406
3407 /* spawnvp has three arguments: (mode, path, argv), where
3408 argv is a list or tuple of strings. */
3409
3410 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3411 Py_FileSystemDefaultEncoding,
3412 &path, &argv))
3413 return NULL;
3414 if (PyList_Check(argv)) {
3415 argc = PyList_Size(argv);
3416 getitem = PyList_GetItem;
3417 }
3418 else if (PyTuple_Check(argv)) {
3419 argc = PyTuple_Size(argv);
3420 getitem = PyTuple_GetItem;
3421 }
3422 else {
3423 PyErr_SetString(PyExc_TypeError,
3424 "spawnvp() arg 2 must be a tuple or list");
3425 PyMem_Free(path);
3426 return NULL;
3427 }
3428
3429 argvlist = PyMem_NEW(char *, argc+1);
3430 if (argvlist == NULL) {
3431 PyMem_Free(path);
3432 return PyErr_NoMemory();
3433 }
3434 for (i = 0; i < argc; i++) {
3435 if (!PyArg_Parse((*getitem)(argv, i), "et",
3436 Py_FileSystemDefaultEncoding,
3437 &argvlist[i])) {
3438 free_string_array(argvlist, i);
3439 PyErr_SetString(
3440 PyExc_TypeError,
3441 "spawnvp() arg 2 must contain only strings");
3442 PyMem_Free(path);
3443 return NULL;
3444 }
3445 }
3446 argvlist[argc] = NULL;
3447
3448 Py_BEGIN_ALLOW_THREADS
3449#if defined(PYCC_GCC)
3450 spawnval = spawnvp(mode, path, argvlist);
3451#else
3452 spawnval = _spawnvp(mode, path, argvlist);
3453#endif
3454 Py_END_ALLOW_THREADS
3455
3456 free_string_array(argvlist, argc);
3457 PyMem_Free(path);
3458
3459 if (spawnval == -1)
3460 return posix_error();
3461 else
3462 return Py_BuildValue("l", (long) spawnval);
3463}
3464
3465
3466PyDoc_STRVAR(posix_spawnvpe__doc__,
3467"spawnvpe(mode, file, args, env)\n\n\
3468Execute the program 'file' in a new process, using the environment\n\
3469search path to find the file.\n\
3470\n\
3471 mode: mode of process creation\n\
3472 file: executable file name\n\
3473 args: tuple or list of arguments\n\
3474 env: dictionary of strings mapping to strings");
3475
3476static PyObject *
3477posix_spawnvpe(PyObject *self, PyObject *args)
3478{
3479 char *path;
3480 PyObject *argv, *env;
3481 char **argvlist;
3482 char **envlist;
3483 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3484 int mode, i, pos, argc, envc;
3485 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003486 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003487 int lastarg = 0;
3488
3489 /* spawnvpe has four arguments: (mode, path, argv, env), where
3490 argv is a list or tuple of strings and env is a dictionary
3491 like posix.environ. */
3492
3493 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3494 Py_FileSystemDefaultEncoding,
3495 &path, &argv, &env))
3496 return NULL;
3497 if (PyList_Check(argv)) {
3498 argc = PyList_Size(argv);
3499 getitem = PyList_GetItem;
3500 }
3501 else if (PyTuple_Check(argv)) {
3502 argc = PyTuple_Size(argv);
3503 getitem = PyTuple_GetItem;
3504 }
3505 else {
3506 PyErr_SetString(PyExc_TypeError,
3507 "spawnvpe() arg 2 must be a tuple or list");
3508 goto fail_0;
3509 }
3510 if (!PyMapping_Check(env)) {
3511 PyErr_SetString(PyExc_TypeError,
3512 "spawnvpe() arg 3 must be a mapping object");
3513 goto fail_0;
3514 }
3515
3516 argvlist = PyMem_NEW(char *, argc+1);
3517 if (argvlist == NULL) {
3518 PyErr_NoMemory();
3519 goto fail_0;
3520 }
3521 for (i = 0; i < argc; i++) {
3522 if (!PyArg_Parse((*getitem)(argv, i),
3523 "et;spawnvpe() arg 2 must contain only strings",
3524 Py_FileSystemDefaultEncoding,
3525 &argvlist[i]))
3526 {
3527 lastarg = i;
3528 goto fail_1;
3529 }
3530 }
3531 lastarg = argc;
3532 argvlist[argc] = NULL;
3533
3534 i = PyMapping_Size(env);
3535 if (i < 0)
3536 goto fail_1;
3537 envlist = PyMem_NEW(char *, i + 1);
3538 if (envlist == NULL) {
3539 PyErr_NoMemory();
3540 goto fail_1;
3541 }
3542 envc = 0;
3543 keys = PyMapping_Keys(env);
3544 vals = PyMapping_Values(env);
3545 if (!keys || !vals)
3546 goto fail_2;
3547 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3548 PyErr_SetString(PyExc_TypeError,
3549 "spawnvpe(): env.keys() or env.values() is not a list");
3550 goto fail_2;
3551 }
3552
3553 for (pos = 0; pos < i; pos++) {
3554 char *p, *k, *v;
3555 size_t len;
3556
3557 key = PyList_GetItem(keys, pos);
3558 val = PyList_GetItem(vals, pos);
3559 if (!key || !val)
3560 goto fail_2;
3561
3562 if (!PyArg_Parse(
3563 key,
3564 "s;spawnvpe() arg 3 contains a non-string key",
3565 &k) ||
3566 !PyArg_Parse(
3567 val,
3568 "s;spawnvpe() arg 3 contains a non-string value",
3569 &v))
3570 {
3571 goto fail_2;
3572 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003573 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003574 p = PyMem_NEW(char, len);
3575 if (p == NULL) {
3576 PyErr_NoMemory();
3577 goto fail_2;
3578 }
3579 PyOS_snprintf(p, len, "%s=%s", k, v);
3580 envlist[envc++] = p;
3581 }
3582 envlist[envc] = 0;
3583
3584 Py_BEGIN_ALLOW_THREADS
3585#if defined(PYCC_GCC)
Christian Heimes292d3512008-02-03 16:51:08 +00003586 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003587#else
Christian Heimes292d3512008-02-03 16:51:08 +00003588 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003589#endif
3590 Py_END_ALLOW_THREADS
3591
3592 if (spawnval == -1)
3593 (void) posix_error();
3594 else
3595 res = Py_BuildValue("l", (long) spawnval);
3596
3597 fail_2:
3598 while (--envc >= 0)
3599 PyMem_DEL(envlist[envc]);
3600 PyMem_DEL(envlist);
3601 fail_1:
3602 free_string_array(argvlist, lastarg);
3603 Py_XDECREF(vals);
3604 Py_XDECREF(keys);
3605 fail_0:
3606 PyMem_Free(path);
3607 return res;
3608}
3609#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003610#endif /* HAVE_SPAWNV */
3611
3612
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003613#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003614PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003615"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003616Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3617\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003618Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003619
3620static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003621posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003622{
Christian Heimes400adb02008-02-01 08:12:03 +00003623 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003624 if (pid == -1)
3625 return posix_error();
Georg Brandl2ee470f2008-07-16 12:55:28 +00003626 if (pid == 0)
3627 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003628 return PyLong_FromLong(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003629}
3630#endif
3631
3632
Guido van Rossumad0ee831995-03-01 10:34:45 +00003633#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003634PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003635"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003636Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003637Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003638
Barry Warsaw53699e91996-12-10 23:23:01 +00003639static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003640posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003641{
Christian Heimes400adb02008-02-01 08:12:03 +00003642 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003643 if (pid == -1)
3644 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003645 if (pid == 0)
3646 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003647 return PyLong_FromLong(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003648}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003649#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003650
Neal Norwitzb59798b2003-03-21 01:43:31 +00003651/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003652/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3653#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003654#define DEV_PTY_FILE "/dev/ptc"
3655#define HAVE_DEV_PTMX
3656#else
3657#define DEV_PTY_FILE "/dev/ptmx"
3658#endif
3659
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003660#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003661#ifdef HAVE_PTY_H
3662#include <pty.h>
3663#else
3664#ifdef HAVE_LIBUTIL_H
3665#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003666#endif /* HAVE_LIBUTIL_H */
3667#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003668#ifdef HAVE_STROPTS_H
3669#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003670#endif
3671#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003672
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003673#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003674PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003675"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003676Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003677
3678static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003679posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003680{
3681 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003682#ifndef HAVE_OPENPTY
3683 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003684#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003685#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003686 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003687#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003688 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003689#endif
3690#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003691
Thomas Wouters70c21a12000-07-14 14:28:33 +00003692#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003693 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3694 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003695#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003696 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3697 if (slave_name == NULL)
3698 return posix_error();
3699
3700 slave_fd = open(slave_name, O_RDWR);
3701 if (slave_fd < 0)
3702 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003703#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003704 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003705 if (master_fd < 0)
3706 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003707 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003708 /* change permission of slave */
3709 if (grantpt(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 }
3713 /* unlock slave */
3714 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003715 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003716 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003717 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003718 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003719 slave_name = ptsname(master_fd); /* get name of slave */
3720 if (slave_name == NULL)
3721 return posix_error();
3722 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3723 if (slave_fd < 0)
3724 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003725#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003726 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3727 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003728#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003729 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003730#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003731#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003732#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003733
Fred Drake8cef4cf2000-06-28 16:40:38 +00003734 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003735
Fred Drake8cef4cf2000-06-28 16:40:38 +00003736}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003737#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003738
3739#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003740PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003741"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003742Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3743Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003744To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003745
3746static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003747posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003748{
Christian Heimes400adb02008-02-01 08:12:03 +00003749 int master_fd = -1;
3750 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003751
Fred Drake8cef4cf2000-06-28 16:40:38 +00003752 pid = forkpty(&master_fd, NULL, NULL, NULL);
3753 if (pid == -1)
3754 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003755 if (pid == 0)
3756 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003757 return Py_BuildValue("(li)", pid, master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003758}
3759#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003760
Guido van Rossumad0ee831995-03-01 10:34:45 +00003761#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003762PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003763"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003764Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003765
Barry Warsaw53699e91996-12-10 23:23:01 +00003766static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003767posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003768{
Christian Heimes217cfd12007-12-02 14:31:20 +00003769 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003770}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003771#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003772
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003773
Guido van Rossumad0ee831995-03-01 10:34:45 +00003774#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003775PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003776"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003777Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003778
Barry Warsaw53699e91996-12-10 23:23:01 +00003779static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003780posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003781{
Christian Heimes217cfd12007-12-02 14:31:20 +00003782 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003783}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003784#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003785
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003786
Guido van Rossumad0ee831995-03-01 10:34:45 +00003787#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003788PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003789"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003790Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003791
Barry Warsaw53699e91996-12-10 23:23:01 +00003792static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003793posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003794{
Christian Heimes217cfd12007-12-02 14:31:20 +00003795 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003796}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003797#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003798
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003799
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003800PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003801"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003802Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003803
Barry Warsaw53699e91996-12-10 23:23:01 +00003804static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003805posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003806{
Christian Heimes217cfd12007-12-02 14:31:20 +00003807 return PyLong_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003808}
3809
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003810
Fred Drakec9680921999-12-13 16:37:25 +00003811#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003812PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003813"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003814Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003815
3816static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003817posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003818{
3819 PyObject *result = NULL;
3820
Fred Drakec9680921999-12-13 16:37:25 +00003821#ifdef NGROUPS_MAX
3822#define MAX_GROUPS NGROUPS_MAX
3823#else
3824 /* defined to be 16 on Solaris7, so this should be a small number */
3825#define MAX_GROUPS 64
3826#endif
3827 gid_t grouplist[MAX_GROUPS];
3828 int n;
3829
3830 n = getgroups(MAX_GROUPS, grouplist);
3831 if (n < 0)
3832 posix_error();
3833 else {
3834 result = PyList_New(n);
3835 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003836 int i;
3837 for (i = 0; i < n; ++i) {
Christian Heimes217cfd12007-12-02 14:31:20 +00003838 PyObject *o = PyLong_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003839 if (o == NULL) {
3840 Py_DECREF(result);
3841 result = NULL;
3842 break;
3843 }
3844 PyList_SET_ITEM(result, i, o);
3845 }
3846 }
3847 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003848
Fred Drakec9680921999-12-13 16:37:25 +00003849 return result;
3850}
3851#endif
3852
Martin v. Löwis606edc12002-06-13 21:09:11 +00003853#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003854PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003855"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003856Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003857
3858static PyObject *
3859posix_getpgid(PyObject *self, PyObject *args)
3860{
3861 int pid, pgid;
3862 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3863 return NULL;
3864 pgid = getpgid(pid);
3865 if (pgid < 0)
3866 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00003867 return PyLong_FromLong((long)pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00003868}
3869#endif /* HAVE_GETPGID */
3870
3871
Guido van Rossumb6775db1994-08-01 11:34:53 +00003872#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003873PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003874"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003875Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003876
Barry Warsaw53699e91996-12-10 23:23:01 +00003877static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003878posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003879{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003880#ifdef GETPGRP_HAVE_ARG
Christian Heimes217cfd12007-12-02 14:31:20 +00003881 return PyLong_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003882#else /* GETPGRP_HAVE_ARG */
Christian Heimes217cfd12007-12-02 14:31:20 +00003883 return PyLong_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003884#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003885}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003886#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003887
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003888
Guido van Rossumb6775db1994-08-01 11:34:53 +00003889#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003890PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003891"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003892Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003893
Barry Warsaw53699e91996-12-10 23:23:01 +00003894static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003895posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003896{
Guido van Rossum64933891994-10-20 21:56:42 +00003897#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003898 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003899#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003900 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003901#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003902 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003903 Py_INCREF(Py_None);
3904 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003905}
3906
Guido van Rossumb6775db1994-08-01 11:34:53 +00003907#endif /* HAVE_SETPGRP */
3908
Guido van Rossumad0ee831995-03-01 10:34:45 +00003909#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003910PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003911"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003912Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003913
Barry Warsaw53699e91996-12-10 23:23:01 +00003914static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003915posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003916{
Christian Heimes217cfd12007-12-02 14:31:20 +00003917 return PyLong_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003918}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003919#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003920
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003921
Fred Drake12c6e2d1999-12-14 21:25:03 +00003922#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003923PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003924"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003925Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003926
3927static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003928posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003929{
Neal Norwitze241ce82003-02-17 18:17:05 +00003930 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003931 char *name;
3932 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003933
Fred Drakea30680b2000-12-06 21:24:28 +00003934 errno = 0;
3935 name = getlogin();
3936 if (name == NULL) {
3937 if (errno)
3938 posix_error();
3939 else
3940 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003941 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003942 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003943 else
Neal Norwitz93c56822007-08-26 07:10:06 +00003944 result = PyUnicode_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003945 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003946
Fred Drake12c6e2d1999-12-14 21:25:03 +00003947 return result;
3948}
3949#endif
3950
Guido van Rossumad0ee831995-03-01 10:34:45 +00003951#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003952PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003953"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003954Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003955
Barry Warsaw53699e91996-12-10 23:23:01 +00003956static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003957posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003958{
Christian Heimes217cfd12007-12-02 14:31:20 +00003959 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003960}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003961#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003962
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003963
Guido van Rossumad0ee831995-03-01 10:34:45 +00003964#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003965PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003966"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003967Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003968
Barry Warsaw53699e91996-12-10 23:23:01 +00003969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003970posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003971{
Christian Heimes292d3512008-02-03 16:51:08 +00003972 pid_t pid;
3973 int sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003974 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003975 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003976#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003977 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3978 APIRET rc;
3979 if ((rc = DosSendSignalException(pid, sig)) != 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 if (sig == XCPT_SIGNAL_KILLPROC) {
3983 APIRET rc;
3984 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003985 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003986
3987 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003988 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003989#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003990 if (kill(pid, sig) == -1)
3991 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003992#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003993 Py_INCREF(Py_None);
3994 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003995}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003996#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003997
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003998#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003999PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004000"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004001Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004002
4003static PyObject *
4004posix_killpg(PyObject *self, PyObject *args)
4005{
4006 int pgid, sig;
4007 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
4008 return NULL;
4009 if (killpg(pgid, sig) == -1)
4010 return posix_error();
4011 Py_INCREF(Py_None);
4012 return Py_None;
4013}
4014#endif
4015
Guido van Rossumc0125471996-06-28 18:55:32 +00004016#ifdef HAVE_PLOCK
4017
4018#ifdef HAVE_SYS_LOCK_H
4019#include <sys/lock.h>
4020#endif
4021
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004022PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004023"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004024Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004025
Barry Warsaw53699e91996-12-10 23:23:01 +00004026static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004027posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004028{
4029 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004030 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004031 return NULL;
4032 if (plock(op) == -1)
4033 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004034 Py_INCREF(Py_None);
4035 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004036}
4037#endif
4038
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004039
Guido van Rossum3b066191991-06-04 19:40:25 +00004040
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004041
Guido van Rossumb6775db1994-08-01 11:34:53 +00004042#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004043PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004044"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004045Set the current process's user id.");
4046
Barry Warsaw53699e91996-12-10 23:23:01 +00004047static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004048posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004049{
4050 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004051 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004052 return NULL;
4053 if (setuid(uid) < 0)
4054 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004055 Py_INCREF(Py_None);
4056 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004057}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004058#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004059
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004060
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004061#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004062PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004063"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004064Set the current process's effective user id.");
4065
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004066static PyObject *
4067posix_seteuid (PyObject *self, PyObject *args)
4068{
4069 int euid;
4070 if (!PyArg_ParseTuple(args, "i", &euid)) {
4071 return NULL;
4072 } else if (seteuid(euid) < 0) {
4073 return posix_error();
4074 } else {
4075 Py_INCREF(Py_None);
4076 return Py_None;
4077 }
4078}
4079#endif /* HAVE_SETEUID */
4080
4081#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004082PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004083"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004084Set the current process's effective group id.");
4085
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004086static PyObject *
4087posix_setegid (PyObject *self, PyObject *args)
4088{
4089 int egid;
4090 if (!PyArg_ParseTuple(args, "i", &egid)) {
4091 return NULL;
4092 } else if (setegid(egid) < 0) {
4093 return posix_error();
4094 } else {
4095 Py_INCREF(Py_None);
4096 return Py_None;
4097 }
4098}
4099#endif /* HAVE_SETEGID */
4100
4101#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004102PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004103"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004104Set the current process's real and effective user ids.");
4105
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004106static PyObject *
4107posix_setreuid (PyObject *self, PyObject *args)
4108{
4109 int ruid, euid;
4110 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4111 return NULL;
4112 } else if (setreuid(ruid, euid) < 0) {
4113 return posix_error();
4114 } else {
4115 Py_INCREF(Py_None);
4116 return Py_None;
4117 }
4118}
4119#endif /* HAVE_SETREUID */
4120
4121#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004122PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004123"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004124Set the current process's real and effective group ids.");
4125
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004126static PyObject *
4127posix_setregid (PyObject *self, PyObject *args)
4128{
4129 int rgid, egid;
4130 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4131 return NULL;
4132 } else if (setregid(rgid, egid) < 0) {
4133 return posix_error();
4134 } else {
4135 Py_INCREF(Py_None);
4136 return Py_None;
4137 }
4138}
4139#endif /* HAVE_SETREGID */
4140
Guido van Rossumb6775db1994-08-01 11:34:53 +00004141#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004142PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004143"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004144Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004145
Barry Warsaw53699e91996-12-10 23:23:01 +00004146static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004147posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004148{
4149 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004150 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004151 return NULL;
4152 if (setgid(gid) < 0)
4153 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004154 Py_INCREF(Py_None);
4155 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004156}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004157#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004158
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004159#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004160PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004161"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004162Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004163
4164static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004165posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004166{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004167 int i, len;
4168 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004169
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004170 if (!PySequence_Check(groups)) {
4171 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4172 return NULL;
4173 }
4174 len = PySequence_Size(groups);
4175 if (len > MAX_GROUPS) {
4176 PyErr_SetString(PyExc_ValueError, "too many groups");
4177 return NULL;
4178 }
4179 for(i = 0; i < len; i++) {
4180 PyObject *elem;
4181 elem = PySequence_GetItem(groups, i);
4182 if (!elem)
4183 return NULL;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004184 if (!PyLong_Check(elem)) {
4185 PyErr_SetString(PyExc_TypeError,
4186 "groups must be integers");
4187 Py_DECREF(elem);
4188 return NULL;
4189 } else {
4190 unsigned long x = PyLong_AsUnsignedLong(elem);
4191 if (PyErr_Occurred()) {
4192 PyErr_SetString(PyExc_TypeError,
4193 "group id too big");
Georg Brandla13c2442005-11-22 19:30:31 +00004194 Py_DECREF(elem);
4195 return NULL;
Georg Brandla13c2442005-11-22 19:30:31 +00004196 }
Georg Brandla13c2442005-11-22 19:30:31 +00004197 grouplist[i] = x;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004198 /* read back the value to see if it fitted in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00004199 if (grouplist[i] != x) {
4200 PyErr_SetString(PyExc_TypeError,
4201 "group id too big");
4202 Py_DECREF(elem);
4203 return NULL;
4204 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004205 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004206 Py_DECREF(elem);
4207 }
4208
4209 if (setgroups(len, grouplist) < 0)
4210 return posix_error();
4211 Py_INCREF(Py_None);
4212 return Py_None;
4213}
4214#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004215
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004216#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4217static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004218wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004219{
4220 PyObject *result;
4221 static PyObject *struct_rusage;
4222
4223 if (pid == -1)
4224 return posix_error();
4225
4226 if (struct_rusage == NULL) {
Christian Heimes072c0f12008-01-03 23:01:04 +00004227 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004228 if (m == NULL)
4229 return NULL;
4230 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4231 Py_DECREF(m);
4232 if (struct_rusage == NULL)
4233 return NULL;
4234 }
4235
4236 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4237 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4238 if (!result)
4239 return NULL;
4240
4241#ifndef doubletime
4242#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4243#endif
4244
4245 PyStructSequence_SET_ITEM(result, 0,
4246 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4247 PyStructSequence_SET_ITEM(result, 1,
4248 PyFloat_FromDouble(doubletime(ru->ru_stime)));
4249#define SET_INT(result, index, value)\
Christian Heimes217cfd12007-12-02 14:31:20 +00004250 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004251 SET_INT(result, 2, ru->ru_maxrss);
4252 SET_INT(result, 3, ru->ru_ixrss);
4253 SET_INT(result, 4, ru->ru_idrss);
4254 SET_INT(result, 5, ru->ru_isrss);
4255 SET_INT(result, 6, ru->ru_minflt);
4256 SET_INT(result, 7, ru->ru_majflt);
4257 SET_INT(result, 8, ru->ru_nswap);
4258 SET_INT(result, 9, ru->ru_inblock);
4259 SET_INT(result, 10, ru->ru_oublock);
4260 SET_INT(result, 11, ru->ru_msgsnd);
4261 SET_INT(result, 12, ru->ru_msgrcv);
4262 SET_INT(result, 13, ru->ru_nsignals);
4263 SET_INT(result, 14, ru->ru_nvcsw);
4264 SET_INT(result, 15, ru->ru_nivcsw);
4265#undef SET_INT
4266
4267 if (PyErr_Occurred()) {
4268 Py_DECREF(result);
4269 return NULL;
4270 }
4271
4272 return Py_BuildValue("iiN", pid, status, result);
4273}
4274#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4275
4276#ifdef HAVE_WAIT3
4277PyDoc_STRVAR(posix_wait3__doc__,
4278"wait3(options) -> (pid, status, rusage)\n\n\
4279Wait for completion of a child process.");
4280
4281static PyObject *
4282posix_wait3(PyObject *self, PyObject *args)
4283{
Christian Heimes292d3512008-02-03 16:51:08 +00004284 pid_t pid;
4285 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004286 struct rusage ru;
4287 WAIT_TYPE status;
4288 WAIT_STATUS_INT(status) = 0;
4289
4290 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4291 return NULL;
4292
4293 Py_BEGIN_ALLOW_THREADS
4294 pid = wait3(&status, options, &ru);
4295 Py_END_ALLOW_THREADS
4296
4297 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4298}
4299#endif /* HAVE_WAIT3 */
4300
4301#ifdef HAVE_WAIT4
4302PyDoc_STRVAR(posix_wait4__doc__,
4303"wait4(pid, options) -> (pid, status, rusage)\n\n\
4304Wait for completion of a given child process.");
4305
4306static PyObject *
4307posix_wait4(PyObject *self, PyObject *args)
4308{
Christian Heimes292d3512008-02-03 16:51:08 +00004309 pid_t pid;
4310 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004311 struct rusage ru;
4312 WAIT_TYPE status;
4313 WAIT_STATUS_INT(status) = 0;
4314
4315 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
4316 return NULL;
4317
4318 Py_BEGIN_ALLOW_THREADS
4319 pid = wait4(pid, &status, options, &ru);
4320 Py_END_ALLOW_THREADS
4321
4322 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4323}
4324#endif /* HAVE_WAIT4 */
4325
Guido van Rossumb6775db1994-08-01 11:34:53 +00004326#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004327PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004328"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004329Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004330
Barry Warsaw53699e91996-12-10 23:23:01 +00004331static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004332posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004333{
Christian Heimes292d3512008-02-03 16:51:08 +00004334 pid_t pid;
4335 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004336 WAIT_TYPE status;
4337 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004338
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004339 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004340 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004341 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004342 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004343 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004344 if (pid == -1)
4345 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004346
4347 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004348}
4349
Tim Petersab034fa2002-02-01 11:27:43 +00004350#elif defined(HAVE_CWAIT)
4351
4352/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004353PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004354"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004355"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004356
4357static PyObject *
4358posix_waitpid(PyObject *self, PyObject *args)
4359{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004360 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004361 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004362
4363 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4364 return NULL;
4365 Py_BEGIN_ALLOW_THREADS
4366 pid = _cwait(&status, pid, options);
4367 Py_END_ALLOW_THREADS
4368 if (pid == -1)
4369 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004370
4371 /* shift the status left a byte so this is more like the POSIX waitpid */
4372 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004373}
4374#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004375
Guido van Rossumad0ee831995-03-01 10:34:45 +00004376#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004377PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004378"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004379Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004380
Barry Warsaw53699e91996-12-10 23:23:01 +00004381static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004382posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004383{
Christian Heimes292d3512008-02-03 16:51:08 +00004384 pid_t pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004385 WAIT_TYPE status;
4386 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004387
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004388 Py_BEGIN_ALLOW_THREADS
4389 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004390 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004391 if (pid == -1)
4392 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004393
4394 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004395}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004396#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004397
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004398
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004399PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004400"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004401Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004402
Barry Warsaw53699e91996-12-10 23:23:01 +00004403static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004404posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004405{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004406#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004407 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004408#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004409#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00004410 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004411#else
4412 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4413#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004414#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004415}
4416
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004417
Guido van Rossumb6775db1994-08-01 11:34:53 +00004418#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004419PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004420"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004421Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004422
Barry Warsaw53699e91996-12-10 23:23:01 +00004423static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004424posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004425{
Thomas Wouters89f507f2006-12-13 04:49:30 +00004426 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004427 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004428 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004429 int n;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004430 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004431
4432 if (!PyArg_ParseTuple(args, "et:readlink",
4433 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004434 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004435 v = PySequence_GetItem(args, 0);
Neal Norwitzcda5c062007-08-12 17:09:36 +00004436 if (v == NULL) {
4437 PyMem_Free(path);
4438 return NULL;
4439 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004440
4441 if (PyUnicode_Check(v)) {
4442 arg_is_unicode = 1;
4443 }
4444 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004445
Barry Warsaw53699e91996-12-10 23:23:01 +00004446 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004447 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004448 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004449 if (n < 0)
Neal Norwitzfca70052007-08-12 16:56:02 +00004450 return posix_error_with_allocated_filename(path);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004451
Neal Norwitzfca70052007-08-12 16:56:02 +00004452 PyMem_Free(path);
Christian Heimes72b710a2008-05-26 13:28:38 +00004453 v = PyBytes_FromStringAndSize(buf, n);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004454 if (arg_is_unicode) {
4455 PyObject *w;
4456
4457 w = PyUnicode_FromEncodedObject(v,
4458 Py_FileSystemDefaultEncoding,
4459 "strict");
4460 if (w != NULL) {
4461 Py_DECREF(v);
4462 v = w;
4463 }
4464 else {
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004465 v = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004466 }
4467 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004468 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004469}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004470#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004472
Guido van Rossumb6775db1994-08-01 11:34:53 +00004473#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004474PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004475"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004476Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004477
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004478static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004479posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004480{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004481 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004482}
4483#endif /* HAVE_SYMLINK */
4484
4485
4486#ifdef HAVE_TIMES
4487#ifndef HZ
4488#define HZ 60 /* Universal constant :-) */
4489#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004490
Guido van Rossumd48f2521997-12-05 22:19:34 +00004491#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4492static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004493system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004494{
4495 ULONG value = 0;
4496
4497 Py_BEGIN_ALLOW_THREADS
4498 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4499 Py_END_ALLOW_THREADS
4500
4501 return value;
4502}
4503
4504static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004505posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004506{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004507 /* Currently Only Uptime is Provided -- Others Later */
4508 return Py_BuildValue("ddddd",
4509 (double)0 /* t.tms_utime / HZ */,
4510 (double)0 /* t.tms_stime / HZ */,
4511 (double)0 /* t.tms_cutime / HZ */,
4512 (double)0 /* t.tms_cstime / HZ */,
4513 (double)system_uptime() / 1000);
4514}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004515#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004516static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004517posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004518{
4519 struct tms t;
4520 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004521 errno = 0;
4522 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004523 if (c == (clock_t) -1)
4524 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004525 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004526 (double)t.tms_utime / HZ,
4527 (double)t.tms_stime / HZ,
4528 (double)t.tms_cutime / HZ,
4529 (double)t.tms_cstime / HZ,
4530 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004531}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004532#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004533#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004534
4535
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004536#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004537#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004538static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004539posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004540{
4541 FILETIME create, exit, kernel, user;
4542 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004543 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004544 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4545 /* The fields of a FILETIME structure are the hi and lo part
4546 of a 64-bit value expressed in 100 nanosecond units.
4547 1e7 is one second in such units; 1e-7 the inverse.
4548 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4549 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004550 return Py_BuildValue(
4551 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004552 (double)(user.dwHighDateTime*429.4967296 +
4553 user.dwLowDateTime*1e-7),
Christian Heimes68f5fbe2008-02-14 08:27:37 +00004554 (double)(kernel.dwHighDateTime*429.4967296 +
4555 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004556 (double)0,
4557 (double)0,
4558 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004559}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004560#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004561
4562#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004563PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004564"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004565Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004566#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004567
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004568
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004569#ifdef HAVE_GETSID
4570PyDoc_STRVAR(posix_getsid__doc__,
4571"getsid(pid) -> sid\n\n\
4572Call the system call getsid().");
4573
4574static PyObject *
4575posix_getsid(PyObject *self, PyObject *args)
4576{
Christian Heimes292d3512008-02-03 16:51:08 +00004577 pid_t pid;
4578 int sid;
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004579 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
4580 return NULL;
4581 sid = getsid(pid);
4582 if (sid < 0)
4583 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004584 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004585}
4586#endif /* HAVE_GETSID */
4587
4588
Guido van Rossumb6775db1994-08-01 11:34:53 +00004589#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004590PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004591"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004592Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004593
Barry Warsaw53699e91996-12-10 23:23:01 +00004594static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004595posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004596{
Guido van Rossum687dd131993-05-17 08:34:16 +00004597 if (setsid() < 0)
4598 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004599 Py_INCREF(Py_None);
4600 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004601}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004602#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004603
Guido van Rossumb6775db1994-08-01 11:34:53 +00004604#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004605PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004606"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004607Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004608
Barry Warsaw53699e91996-12-10 23:23:01 +00004609static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004610posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004611{
Christian Heimes292d3512008-02-03 16:51:08 +00004612 pid_t pid;
4613 int pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004614 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004615 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004616 if (setpgid(pid, pgrp) < 0)
4617 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004618 Py_INCREF(Py_None);
4619 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004620}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004621#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004622
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004623
Guido van Rossumb6775db1994-08-01 11:34:53 +00004624#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004625PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004626"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004627Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004628
Barry Warsaw53699e91996-12-10 23:23:01 +00004629static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004630posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004631{
Christian Heimes15ebc882008-02-04 18:48:49 +00004632 int fd;
4633 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004634 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004635 return NULL;
4636 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004637 if (pgid < 0)
4638 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004639 return PyLong_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004640}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004641#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004642
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004643
Guido van Rossumb6775db1994-08-01 11:34:53 +00004644#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004645PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004646"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004647Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004648
Barry Warsaw53699e91996-12-10 23:23:01 +00004649static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004650posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004651{
4652 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004653 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004654 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004655 if (tcsetpgrp(fd, pgid) < 0)
4656 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004657 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004658 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004659}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004660#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004661
Guido van Rossum687dd131993-05-17 08:34:16 +00004662/* Functions acting on file descriptors */
4663
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004664PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004665"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004666Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004667
Barry Warsaw53699e91996-12-10 23:23:01 +00004668static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004669posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004670{
Mark Hammondef8b6542001-05-13 08:04:26 +00004671 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004672 int flag;
4673 int mode = 0777;
4674 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004675
4676#ifdef MS_WINDOWS
4677 if (unicode_file_names()) {
4678 PyUnicodeObject *po;
4679 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4680 Py_BEGIN_ALLOW_THREADS
4681 /* PyUnicode_AS_UNICODE OK without thread
4682 lock as it is a simple dereference. */
4683 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4684 Py_END_ALLOW_THREADS
4685 if (fd < 0)
4686 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004687 return PyLong_FromLong((long)fd);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004688 }
4689 /* Drop the argument parsing error as narrow strings
4690 are also valid. */
4691 PyErr_Clear();
4692 }
4693#endif
4694
Tim Peters5aa91602002-01-30 05:46:57 +00004695 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004696 Py_FileSystemDefaultEncoding, &file,
4697 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004698 return NULL;
4699
Barry Warsaw53699e91996-12-10 23:23:01 +00004700 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004701 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004702 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004703 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004704 return posix_error_with_allocated_filename(file);
4705 PyMem_Free(file);
Christian Heimes217cfd12007-12-02 14:31:20 +00004706 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004707}
4708
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004709
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004710PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004711"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004712Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004713
Barry Warsaw53699e91996-12-10 23:23:01 +00004714static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004715posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004716{
4717 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004718 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004719 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004720 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004721 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004722 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004723 if (res < 0)
4724 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004725 Py_INCREF(Py_None);
4726 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004727}
4728
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004729
Christian Heimesfdab48e2008-01-20 09:06:41 +00004730PyDoc_STRVAR(posix_closerange__doc__,
4731"closerange(fd_low, fd_high)\n\n\
4732Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
4733
4734static PyObject *
4735posix_closerange(PyObject *self, PyObject *args)
4736{
4737 int fd_from, fd_to, i;
4738 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
4739 return NULL;
4740 Py_BEGIN_ALLOW_THREADS
4741 for (i = fd_from; i < fd_to; i++)
4742 close(i);
4743 Py_END_ALLOW_THREADS
4744 Py_RETURN_NONE;
4745}
4746
4747
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004748PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004749"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004750Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004751
Barry Warsaw53699e91996-12-10 23:23:01 +00004752static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004753posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004754{
4755 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004756 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004757 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004758 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004759 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004760 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004761 if (fd < 0)
4762 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004763 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004764}
4765
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004766
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004767PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00004768"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004769Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004770
Barry Warsaw53699e91996-12-10 23:23:01 +00004771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004772posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004773{
4774 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004775 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004776 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004777 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004778 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004779 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004780 if (res < 0)
4781 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004782 Py_INCREF(Py_None);
4783 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004784}
4785
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004786
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004787PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004788"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004789Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004790
Barry Warsaw53699e91996-12-10 23:23:01 +00004791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004792posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004793{
4794 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004795#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00004796 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004797#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004798 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004799#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004800 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004801 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004802 return NULL;
4803#ifdef SEEK_SET
4804 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4805 switch (how) {
4806 case 0: how = SEEK_SET; break;
4807 case 1: how = SEEK_CUR; break;
4808 case 2: how = SEEK_END; break;
4809 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004810#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004811
4812#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00004813 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004814#else
4815 pos = PyLong_Check(posobj) ?
Christian Heimes217cfd12007-12-02 14:31:20 +00004816 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004817#endif
4818 if (PyErr_Occurred())
4819 return NULL;
4820
Barry Warsaw53699e91996-12-10 23:23:01 +00004821 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004822#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004823 res = _lseeki64(fd, pos, how);
4824#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004825 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004826#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004827 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004828 if (res < 0)
4829 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004830
4831#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00004832 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004833#else
4834 return PyLong_FromLongLong(res);
4835#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004836}
4837
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004838
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004839PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004840"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004841Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004842
Barry Warsaw53699e91996-12-10 23:23:01 +00004843static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004844posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004845{
Guido van Rossum572dbf82007-04-27 23:53:51 +00004846 int fd, size;
4847 Py_ssize_t n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004848 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004849 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004850 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00004851 if (size < 0) {
4852 errno = EINVAL;
4853 return posix_error();
4854 }
Christian Heimes72b710a2008-05-26 13:28:38 +00004855 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004856 if (buffer == NULL)
4857 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004858 Py_BEGIN_ALLOW_THREADS
Christian Heimes72b710a2008-05-26 13:28:38 +00004859 n = read(fd, PyBytes_AS_STRING(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004860 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004861 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004862 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004863 return posix_error();
4864 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004865 if (n != size)
Christian Heimes72b710a2008-05-26 13:28:38 +00004866 _PyBytes_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004867 return buffer;
4868}
4869
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004870
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004871PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004872"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004873Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004874
Barry Warsaw53699e91996-12-10 23:23:01 +00004875static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004876posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004877{
Martin v. Löwis423be952008-08-13 15:53:07 +00004878 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004879 int fd;
4880 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004881
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +00004882 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00004883 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004884 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis423be952008-08-13 15:53:07 +00004885 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00004886 Py_END_ALLOW_THREADS
Martin v. Löwis423be952008-08-13 15:53:07 +00004887 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00004888 if (size < 0)
4889 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004890 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004891}
4892
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004893
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004894PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004895"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004896Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004897
Barry Warsaw53699e91996-12-10 23:23:01 +00004898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004899posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004900{
4901 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004902 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004903 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004904 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004905 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00004906#ifdef __VMS
4907 /* on OpenVMS we must ensure that all bytes are written to the file */
4908 fsync(fd);
4909#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004910 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004911 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004912 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00004913 if (res != 0) {
4914#ifdef MS_WINDOWS
4915 return win32_error("fstat", NULL);
4916#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004917 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00004918#endif
4919 }
Tim Peters5aa91602002-01-30 05:46:57 +00004920
Martin v. Löwis14694662006-02-03 12:54:16 +00004921 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004922}
4923
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004924PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004925"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004926Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004927connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004928
4929static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004930posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004931{
4932 int fd;
4933 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4934 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004935 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004936}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004937
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004938#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004939PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004940"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004941Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004942
Barry Warsaw53699e91996-12-10 23:23:01 +00004943static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004944posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00004945{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004946#if defined(PYOS_OS2)
4947 HFILE read, write;
4948 APIRET rc;
4949
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004950 Py_BEGIN_ALLOW_THREADS
4951 rc = DosCreatePipe( &read, &write, 4096);
4952 Py_END_ALLOW_THREADS
4953 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004954 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004955
4956 return Py_BuildValue("(ii)", read, write);
4957#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004958#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00004959 int fds[2];
4960 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00004961 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004962 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004963 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004964 if (res != 0)
4965 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004966 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004967#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00004968 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004969 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004970 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00004971 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004972 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004973 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004974 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004975 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004976 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4977 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004978 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004979#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004980#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004981}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004982#endif /* HAVE_PIPE */
4983
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004984
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004985#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004986PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00004987"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004988Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004989
Barry Warsaw53699e91996-12-10 23:23:01 +00004990static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004991posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004992{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004993 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004994 int mode = 0666;
4995 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004996 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004997 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004998 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004999 res = mkfifo(filename, mode);
5000 Py_END_ALLOW_THREADS
5001 if (res < 0)
5002 return posix_error();
5003 Py_INCREF(Py_None);
5004 return Py_None;
5005}
5006#endif
5007
5008
Neal Norwitz11690112002-07-30 01:08:28 +00005009#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005010PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005011"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005012Create a filesystem node (file, device special file or named pipe)\n\
5013named filename. mode specifies both the permissions to use and the\n\
5014type of node to be created, being combined (bitwise OR) with one of\n\
5015S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005016device defines the newly created device special file (probably using\n\
5017os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005018
5019
5020static PyObject *
5021posix_mknod(PyObject *self, PyObject *args)
5022{
5023 char *filename;
5024 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005025 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005026 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005027 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005028 return NULL;
5029 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005030 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005031 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005032 if (res < 0)
5033 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005034 Py_INCREF(Py_None);
5035 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005036}
5037#endif
5038
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005039#ifdef HAVE_DEVICE_MACROS
5040PyDoc_STRVAR(posix_major__doc__,
5041"major(device) -> major number\n\
5042Extracts a device major number from a raw device number.");
5043
5044static PyObject *
5045posix_major(PyObject *self, PyObject *args)
5046{
5047 int device;
5048 if (!PyArg_ParseTuple(args, "i:major", &device))
5049 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005050 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005051}
5052
5053PyDoc_STRVAR(posix_minor__doc__,
5054"minor(device) -> minor number\n\
5055Extracts a device minor number from a raw device number.");
5056
5057static PyObject *
5058posix_minor(PyObject *self, PyObject *args)
5059{
5060 int device;
5061 if (!PyArg_ParseTuple(args, "i:minor", &device))
5062 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005063 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005064}
5065
5066PyDoc_STRVAR(posix_makedev__doc__,
5067"makedev(major, minor) -> device number\n\
5068Composes a raw device number from the major and minor device numbers.");
5069
5070static PyObject *
5071posix_makedev(PyObject *self, PyObject *args)
5072{
5073 int major, minor;
5074 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5075 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005076 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005077}
5078#endif /* device macros */
5079
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005080
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005081#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005082PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005083"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005084Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005085
Barry Warsaw53699e91996-12-10 23:23:01 +00005086static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005087posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005088{
5089 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005090 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005091 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005092 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005093
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005094 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005095 return NULL;
5096
5097#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005098 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005099#else
5100 length = PyLong_Check(lenobj) ?
Christian Heimes217cfd12007-12-02 14:31:20 +00005101 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005102#endif
5103 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005104 return NULL;
5105
Barry Warsaw53699e91996-12-10 23:23:01 +00005106 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005107 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005108 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005109 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005110 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005111 return NULL;
5112 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005113 Py_INCREF(Py_None);
5114 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005115}
5116#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005117
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005118#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005119PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005120"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005121Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005122
Fred Drake762e2061999-08-26 17:23:54 +00005123/* Save putenv() parameters as values here, so we can collect them when they
5124 * get re-set with another call for the same key. */
5125static PyObject *posix_putenv_garbage;
5126
Tim Peters5aa91602002-01-30 05:46:57 +00005127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005128posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005129{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005130#ifdef MS_WINDOWS
5131 wchar_t *s1, *s2;
5132 wchar_t *newenv;
5133#else
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005134 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005135 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005136#endif
Fred Drake762e2061999-08-26 17:23:54 +00005137 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005138 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005139
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005140 if (!PyArg_ParseTuple(args,
5141#ifdef MS_WINDOWS
5142 "uu:putenv",
5143#else
5144 "ss:putenv",
5145#endif
5146 &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005147 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005148
5149#if defined(PYOS_OS2)
5150 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5151 APIRET rc;
5152
Guido van Rossumd48f2521997-12-05 22:19:34 +00005153 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5154 if (rc != NO_ERROR)
5155 return os2_error(rc);
5156
5157 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5158 APIRET rc;
5159
Guido van Rossumd48f2521997-12-05 22:19:34 +00005160 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5161 if (rc != NO_ERROR)
5162 return os2_error(rc);
5163 } else {
5164#endif
Fred Drake762e2061999-08-26 17:23:54 +00005165 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005166 /* len includes space for a trailing \0; the size arg to
Christian Heimes72b710a2008-05-26 13:28:38 +00005167 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005168#ifdef MS_WINDOWS
5169 len = wcslen(s1) + wcslen(s2) + 2;
5170 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
5171#else
5172 len = strlen(s1) + strlen(s2) + 2;
Christian Heimes72b710a2008-05-26 13:28:38 +00005173 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005174#endif
Fred Drake762e2061999-08-26 17:23:54 +00005175 if (newstr == NULL)
5176 return PyErr_NoMemory();
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005177#ifdef MS_WINDOWS
5178 newenv = PyUnicode_AsUnicode(newstr);
5179 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5180 if (_wputenv(newenv)) {
5181 Py_DECREF(newstr);
5182 posix_error();
5183 return NULL;
5184 }
5185#else
Christian Heimes72b710a2008-05-26 13:28:38 +00005186 newenv = PyBytes_AS_STRING(newstr);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005187 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5188 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005189 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005190 posix_error();
5191 return NULL;
5192 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005193#endif
Fred Drake762e2061999-08-26 17:23:54 +00005194 /* Install the first arg and newstr in posix_putenv_garbage;
5195 * this will cause previous value to be collected. This has to
5196 * happen after the real putenv() call because the old value
5197 * was still accessible until then. */
5198 if (PyDict_SetItem(posix_putenv_garbage,
5199 PyTuple_GET_ITEM(args, 0), newstr)) {
5200 /* really not much we can do; just leak */
5201 PyErr_Clear();
5202 }
5203 else {
5204 Py_DECREF(newstr);
5205 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005206
5207#if defined(PYOS_OS2)
5208 }
5209#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005210 Py_INCREF(Py_None);
5211 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005212}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005213#endif /* putenv */
5214
Guido van Rossumc524d952001-10-19 01:31:59 +00005215#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005216PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005217"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005218Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005219
5220static PyObject *
5221posix_unsetenv(PyObject *self, PyObject *args)
5222{
5223 char *s1;
5224
5225 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5226 return NULL;
5227
5228 unsetenv(s1);
5229
5230 /* Remove the key from posix_putenv_garbage;
5231 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005232 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005233 * old value was still accessible until then.
5234 */
5235 if (PyDict_DelItem(posix_putenv_garbage,
5236 PyTuple_GET_ITEM(args, 0))) {
5237 /* really not much we can do; just leak */
5238 PyErr_Clear();
5239 }
5240
5241 Py_INCREF(Py_None);
5242 return Py_None;
5243}
5244#endif /* unsetenv */
5245
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005246PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005247"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005248Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005249
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005251posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005252{
5253 int code;
5254 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005255 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005256 return NULL;
5257 message = strerror(code);
5258 if (message == NULL) {
5259 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005260 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005261 return NULL;
5262 }
Neal Norwitz93c56822007-08-26 07:10:06 +00005263 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005264}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005265
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005266
Guido van Rossumc9641791998-08-04 15:26:23 +00005267#ifdef HAVE_SYS_WAIT_H
5268
Fred Drake106c1a02002-04-23 15:58:02 +00005269#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005270PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005271"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005272Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005273
5274static PyObject *
5275posix_WCOREDUMP(PyObject *self, PyObject *args)
5276{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005277 WAIT_TYPE status;
5278 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005279
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005280 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005281 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005282
5283 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005284}
5285#endif /* WCOREDUMP */
5286
5287#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005288PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005289"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005290Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005291job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005292
5293static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005294posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005295{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005296 WAIT_TYPE status;
5297 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005298
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005299 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005300 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005301
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005302 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005303}
5304#endif /* WIFCONTINUED */
5305
Guido van Rossumc9641791998-08-04 15:26:23 +00005306#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005307PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005308"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005309Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005310
5311static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005312posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005313{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005314 WAIT_TYPE status;
5315 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005316
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005317 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005318 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005319
Fred Drake106c1a02002-04-23 15:58:02 +00005320 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005321}
5322#endif /* WIFSTOPPED */
5323
5324#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005325PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005326"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005327Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005328
5329static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005330posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005331{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005332 WAIT_TYPE status;
5333 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005334
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005335 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005336 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005337
Fred Drake106c1a02002-04-23 15:58:02 +00005338 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005339}
5340#endif /* WIFSIGNALED */
5341
5342#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005343PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005344"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005345Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005346system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005347
5348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005349posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005350{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005351 WAIT_TYPE status;
5352 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005353
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005354 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005355 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005356
Fred Drake106c1a02002-04-23 15:58:02 +00005357 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005358}
5359#endif /* WIFEXITED */
5360
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005361#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005362PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005363"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005364Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005365
5366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005367posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005368{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005369 WAIT_TYPE status;
5370 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005371
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005372 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005373 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005374
Guido van Rossumc9641791998-08-04 15:26:23 +00005375 return Py_BuildValue("i", WEXITSTATUS(status));
5376}
5377#endif /* WEXITSTATUS */
5378
5379#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005380PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005381"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005382Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005383value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005384
5385static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005386posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005387{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005388 WAIT_TYPE status;
5389 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005390
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005391 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005392 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005393
Guido van Rossumc9641791998-08-04 15:26:23 +00005394 return Py_BuildValue("i", WTERMSIG(status));
5395}
5396#endif /* WTERMSIG */
5397
5398#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005399PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005400"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005401Return the signal that stopped the process that provided\n\
5402the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005403
5404static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005405posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005406{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005407 WAIT_TYPE status;
5408 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005409
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005410 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005411 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005412
Guido van Rossumc9641791998-08-04 15:26:23 +00005413 return Py_BuildValue("i", WSTOPSIG(status));
5414}
5415#endif /* WSTOPSIG */
5416
5417#endif /* HAVE_SYS_WAIT_H */
5418
5419
Thomas Wouters477c8d52006-05-27 19:21:47 +00005420#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005421#ifdef _SCO_DS
5422/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5423 needed definitions in sys/statvfs.h */
5424#define _SVID3
5425#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005426#include <sys/statvfs.h>
5427
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005428static PyObject*
5429_pystatvfs_fromstructstatvfs(struct statvfs st) {
5430 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5431 if (v == NULL)
5432 return NULL;
5433
5434#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005435 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5436 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5437 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
5438 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
5439 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
5440 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
5441 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
5442 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
5443 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5444 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005445#else
Christian Heimes217cfd12007-12-02 14:31:20 +00005446 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5447 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005448 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005449 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005450 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005451 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005452 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005453 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005454 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005455 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005456 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005457 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005458 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005459 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Christian Heimes217cfd12007-12-02 14:31:20 +00005460 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5461 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005462#endif
5463
5464 return v;
5465}
5466
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005467PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005468"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005469Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005470
5471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005472posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005473{
5474 int fd, res;
5475 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005476
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005477 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005478 return NULL;
5479 Py_BEGIN_ALLOW_THREADS
5480 res = fstatvfs(fd, &st);
5481 Py_END_ALLOW_THREADS
5482 if (res != 0)
5483 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005484
5485 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005486}
Thomas Wouters477c8d52006-05-27 19:21:47 +00005487#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005488
5489
Thomas Wouters477c8d52006-05-27 19:21:47 +00005490#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005491#include <sys/statvfs.h>
5492
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005493PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005494"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005495Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005496
5497static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005498posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005499{
5500 char *path;
5501 int res;
5502 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005503 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005504 return NULL;
5505 Py_BEGIN_ALLOW_THREADS
5506 res = statvfs(path, &st);
5507 Py_END_ALLOW_THREADS
5508 if (res != 0)
5509 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005510
5511 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005512}
5513#endif /* HAVE_STATVFS */
5514
Fred Drakec9680921999-12-13 16:37:25 +00005515/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5516 * It maps strings representing configuration variable names to
5517 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005518 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005519 * rarely-used constants. There are three separate tables that use
5520 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005521 *
5522 * This code is always included, even if none of the interfaces that
5523 * need it are included. The #if hackery needed to avoid it would be
5524 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005525 */
5526struct constdef {
5527 char *name;
5528 long value;
5529};
5530
Fred Drake12c6e2d1999-12-14 21:25:03 +00005531static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005532conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005533 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005534{
Christian Heimes217cfd12007-12-02 14:31:20 +00005535 if (PyLong_Check(arg)) {
5536 *valuep = PyLong_AS_LONG(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005537 return 1;
5538 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00005539 else {
Fred Drake12c6e2d1999-12-14 21:25:03 +00005540 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005541 size_t lo = 0;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005542 size_t mid;
Fred Drake699f3522000-06-29 21:12:41 +00005543 size_t hi = tablesize;
5544 int cmp;
Guido van Rossumbce56a62007-05-10 18:04:33 +00005545 const char *confname;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005546 if (!PyUnicode_Check(arg)) {
Guido van Rossumbce56a62007-05-10 18:04:33 +00005547 PyErr_SetString(PyExc_TypeError,
5548 "configuration names must be strings or integers");
5549 return 0;
5550 }
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00005551 confname = _PyUnicode_AsString(arg);
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005552 if (confname == NULL)
5553 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005554 while (lo < hi) {
5555 mid = (lo + hi) / 2;
5556 cmp = strcmp(confname, table[mid].name);
5557 if (cmp < 0)
5558 hi = mid;
5559 else if (cmp > 0)
5560 lo = mid + 1;
5561 else {
5562 *valuep = table[mid].value;
5563 return 1;
5564 }
5565 }
5566 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Guido van Rossumbce56a62007-05-10 18:04:33 +00005567 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005568 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005569}
5570
5571
5572#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5573static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005574#ifdef _PC_ABI_AIO_XFER_MAX
5575 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5576#endif
5577#ifdef _PC_ABI_ASYNC_IO
5578 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5579#endif
Fred Drakec9680921999-12-13 16:37:25 +00005580#ifdef _PC_ASYNC_IO
5581 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5582#endif
5583#ifdef _PC_CHOWN_RESTRICTED
5584 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5585#endif
5586#ifdef _PC_FILESIZEBITS
5587 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5588#endif
5589#ifdef _PC_LAST
5590 {"PC_LAST", _PC_LAST},
5591#endif
5592#ifdef _PC_LINK_MAX
5593 {"PC_LINK_MAX", _PC_LINK_MAX},
5594#endif
5595#ifdef _PC_MAX_CANON
5596 {"PC_MAX_CANON", _PC_MAX_CANON},
5597#endif
5598#ifdef _PC_MAX_INPUT
5599 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5600#endif
5601#ifdef _PC_NAME_MAX
5602 {"PC_NAME_MAX", _PC_NAME_MAX},
5603#endif
5604#ifdef _PC_NO_TRUNC
5605 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5606#endif
5607#ifdef _PC_PATH_MAX
5608 {"PC_PATH_MAX", _PC_PATH_MAX},
5609#endif
5610#ifdef _PC_PIPE_BUF
5611 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5612#endif
5613#ifdef _PC_PRIO_IO
5614 {"PC_PRIO_IO", _PC_PRIO_IO},
5615#endif
5616#ifdef _PC_SOCK_MAXBUF
5617 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5618#endif
5619#ifdef _PC_SYNC_IO
5620 {"PC_SYNC_IO", _PC_SYNC_IO},
5621#endif
5622#ifdef _PC_VDISABLE
5623 {"PC_VDISABLE", _PC_VDISABLE},
5624#endif
5625};
5626
Fred Drakec9680921999-12-13 16:37:25 +00005627static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005628conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005629{
5630 return conv_confname(arg, valuep, posix_constants_pathconf,
5631 sizeof(posix_constants_pathconf)
5632 / sizeof(struct constdef));
5633}
5634#endif
5635
5636#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005637PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005638"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005639Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005640If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005641
5642static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005643posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005644{
5645 PyObject *result = NULL;
5646 int name, fd;
5647
Fred Drake12c6e2d1999-12-14 21:25:03 +00005648 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5649 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005650 long limit;
5651
5652 errno = 0;
5653 limit = fpathconf(fd, name);
5654 if (limit == -1 && errno != 0)
5655 posix_error();
5656 else
Christian Heimes217cfd12007-12-02 14:31:20 +00005657 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005658 }
5659 return result;
5660}
5661#endif
5662
5663
5664#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005665PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005666"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005667Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005668If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005669
5670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005671posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005672{
5673 PyObject *result = NULL;
5674 int name;
5675 char *path;
5676
5677 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5678 conv_path_confname, &name)) {
5679 long limit;
5680
5681 errno = 0;
5682 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005683 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005684 if (errno == EINVAL)
5685 /* could be a path or name problem */
5686 posix_error();
5687 else
5688 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005689 }
Fred Drakec9680921999-12-13 16:37:25 +00005690 else
Christian Heimes217cfd12007-12-02 14:31:20 +00005691 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005692 }
5693 return result;
5694}
5695#endif
5696
5697#ifdef HAVE_CONFSTR
5698static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005699#ifdef _CS_ARCHITECTURE
5700 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5701#endif
5702#ifdef _CS_HOSTNAME
5703 {"CS_HOSTNAME", _CS_HOSTNAME},
5704#endif
5705#ifdef _CS_HW_PROVIDER
5706 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5707#endif
5708#ifdef _CS_HW_SERIAL
5709 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5710#endif
5711#ifdef _CS_INITTAB_NAME
5712 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5713#endif
Fred Drakec9680921999-12-13 16:37:25 +00005714#ifdef _CS_LFS64_CFLAGS
5715 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5716#endif
5717#ifdef _CS_LFS64_LDFLAGS
5718 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5719#endif
5720#ifdef _CS_LFS64_LIBS
5721 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5722#endif
5723#ifdef _CS_LFS64_LINTFLAGS
5724 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5725#endif
5726#ifdef _CS_LFS_CFLAGS
5727 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5728#endif
5729#ifdef _CS_LFS_LDFLAGS
5730 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5731#endif
5732#ifdef _CS_LFS_LIBS
5733 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5734#endif
5735#ifdef _CS_LFS_LINTFLAGS
5736 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5737#endif
Fred Draked86ed291999-12-15 15:34:33 +00005738#ifdef _CS_MACHINE
5739 {"CS_MACHINE", _CS_MACHINE},
5740#endif
Fred Drakec9680921999-12-13 16:37:25 +00005741#ifdef _CS_PATH
5742 {"CS_PATH", _CS_PATH},
5743#endif
Fred Draked86ed291999-12-15 15:34:33 +00005744#ifdef _CS_RELEASE
5745 {"CS_RELEASE", _CS_RELEASE},
5746#endif
5747#ifdef _CS_SRPC_DOMAIN
5748 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5749#endif
5750#ifdef _CS_SYSNAME
5751 {"CS_SYSNAME", _CS_SYSNAME},
5752#endif
5753#ifdef _CS_VERSION
5754 {"CS_VERSION", _CS_VERSION},
5755#endif
Fred Drakec9680921999-12-13 16:37:25 +00005756#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5757 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5758#endif
5759#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5760 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5761#endif
5762#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5763 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5764#endif
5765#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5766 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5767#endif
5768#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5769 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5770#endif
5771#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5772 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5773#endif
5774#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5775 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5776#endif
5777#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5778 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5779#endif
5780#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5781 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5782#endif
5783#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5784 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5785#endif
5786#ifdef _CS_XBS5_LP64_OFF64_LIBS
5787 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5788#endif
5789#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5790 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5791#endif
5792#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5793 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5794#endif
5795#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5796 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5797#endif
5798#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5799 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5800#endif
5801#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5802 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5803#endif
Fred Draked86ed291999-12-15 15:34:33 +00005804#ifdef _MIPS_CS_AVAIL_PROCESSORS
5805 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5806#endif
5807#ifdef _MIPS_CS_BASE
5808 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5809#endif
5810#ifdef _MIPS_CS_HOSTID
5811 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5812#endif
5813#ifdef _MIPS_CS_HW_NAME
5814 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5815#endif
5816#ifdef _MIPS_CS_NUM_PROCESSORS
5817 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5818#endif
5819#ifdef _MIPS_CS_OSREL_MAJ
5820 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5821#endif
5822#ifdef _MIPS_CS_OSREL_MIN
5823 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5824#endif
5825#ifdef _MIPS_CS_OSREL_PATCH
5826 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5827#endif
5828#ifdef _MIPS_CS_OS_NAME
5829 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5830#endif
5831#ifdef _MIPS_CS_OS_PROVIDER
5832 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5833#endif
5834#ifdef _MIPS_CS_PROCESSORS
5835 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5836#endif
5837#ifdef _MIPS_CS_SERIAL
5838 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5839#endif
5840#ifdef _MIPS_CS_VENDOR
5841 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5842#endif
Fred Drakec9680921999-12-13 16:37:25 +00005843};
5844
5845static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005846conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005847{
5848 return conv_confname(arg, valuep, posix_constants_confstr,
5849 sizeof(posix_constants_confstr)
5850 / sizeof(struct constdef));
5851}
5852
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005853PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005854"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005855Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005856
5857static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005858posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005859{
5860 PyObject *result = NULL;
5861 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005862 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00005863
5864 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005865 int len;
Fred Drakec9680921999-12-13 16:37:25 +00005866
Fred Drakec9680921999-12-13 16:37:25 +00005867 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005868 len = confstr(name, buffer, sizeof(buffer));
5869 if (len == 0) {
5870 if (errno) {
5871 posix_error();
5872 }
5873 else {
5874 result = Py_None;
5875 Py_INCREF(Py_None);
5876 }
Fred Drakec9680921999-12-13 16:37:25 +00005877 }
5878 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005879 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00005880 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00005881 if (result != NULL)
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00005882 confstr(name, _PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00005883 }
5884 else
Neal Norwitz93c56822007-08-26 07:10:06 +00005885 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00005886 }
5887 }
5888 return result;
5889}
5890#endif
5891
5892
5893#ifdef HAVE_SYSCONF
5894static struct constdef posix_constants_sysconf[] = {
5895#ifdef _SC_2_CHAR_TERM
5896 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5897#endif
5898#ifdef _SC_2_C_BIND
5899 {"SC_2_C_BIND", _SC_2_C_BIND},
5900#endif
5901#ifdef _SC_2_C_DEV
5902 {"SC_2_C_DEV", _SC_2_C_DEV},
5903#endif
5904#ifdef _SC_2_C_VERSION
5905 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5906#endif
5907#ifdef _SC_2_FORT_DEV
5908 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5909#endif
5910#ifdef _SC_2_FORT_RUN
5911 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5912#endif
5913#ifdef _SC_2_LOCALEDEF
5914 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5915#endif
5916#ifdef _SC_2_SW_DEV
5917 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5918#endif
5919#ifdef _SC_2_UPE
5920 {"SC_2_UPE", _SC_2_UPE},
5921#endif
5922#ifdef _SC_2_VERSION
5923 {"SC_2_VERSION", _SC_2_VERSION},
5924#endif
Fred Draked86ed291999-12-15 15:34:33 +00005925#ifdef _SC_ABI_ASYNCHRONOUS_IO
5926 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5927#endif
5928#ifdef _SC_ACL
5929 {"SC_ACL", _SC_ACL},
5930#endif
Fred Drakec9680921999-12-13 16:37:25 +00005931#ifdef _SC_AIO_LISTIO_MAX
5932 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5933#endif
Fred Drakec9680921999-12-13 16:37:25 +00005934#ifdef _SC_AIO_MAX
5935 {"SC_AIO_MAX", _SC_AIO_MAX},
5936#endif
5937#ifdef _SC_AIO_PRIO_DELTA_MAX
5938 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5939#endif
5940#ifdef _SC_ARG_MAX
5941 {"SC_ARG_MAX", _SC_ARG_MAX},
5942#endif
5943#ifdef _SC_ASYNCHRONOUS_IO
5944 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5945#endif
5946#ifdef _SC_ATEXIT_MAX
5947 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5948#endif
Fred Draked86ed291999-12-15 15:34:33 +00005949#ifdef _SC_AUDIT
5950 {"SC_AUDIT", _SC_AUDIT},
5951#endif
Fred Drakec9680921999-12-13 16:37:25 +00005952#ifdef _SC_AVPHYS_PAGES
5953 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5954#endif
5955#ifdef _SC_BC_BASE_MAX
5956 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5957#endif
5958#ifdef _SC_BC_DIM_MAX
5959 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5960#endif
5961#ifdef _SC_BC_SCALE_MAX
5962 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5963#endif
5964#ifdef _SC_BC_STRING_MAX
5965 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5966#endif
Fred Draked86ed291999-12-15 15:34:33 +00005967#ifdef _SC_CAP
5968 {"SC_CAP", _SC_CAP},
5969#endif
Fred Drakec9680921999-12-13 16:37:25 +00005970#ifdef _SC_CHARCLASS_NAME_MAX
5971 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5972#endif
5973#ifdef _SC_CHAR_BIT
5974 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5975#endif
5976#ifdef _SC_CHAR_MAX
5977 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5978#endif
5979#ifdef _SC_CHAR_MIN
5980 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5981#endif
5982#ifdef _SC_CHILD_MAX
5983 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5984#endif
5985#ifdef _SC_CLK_TCK
5986 {"SC_CLK_TCK", _SC_CLK_TCK},
5987#endif
5988#ifdef _SC_COHER_BLKSZ
5989 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5990#endif
5991#ifdef _SC_COLL_WEIGHTS_MAX
5992 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5993#endif
5994#ifdef _SC_DCACHE_ASSOC
5995 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5996#endif
5997#ifdef _SC_DCACHE_BLKSZ
5998 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5999#endif
6000#ifdef _SC_DCACHE_LINESZ
6001 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6002#endif
6003#ifdef _SC_DCACHE_SZ
6004 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6005#endif
6006#ifdef _SC_DCACHE_TBLKSZ
6007 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6008#endif
6009#ifdef _SC_DELAYTIMER_MAX
6010 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6011#endif
6012#ifdef _SC_EQUIV_CLASS_MAX
6013 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6014#endif
6015#ifdef _SC_EXPR_NEST_MAX
6016 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6017#endif
6018#ifdef _SC_FSYNC
6019 {"SC_FSYNC", _SC_FSYNC},
6020#endif
6021#ifdef _SC_GETGR_R_SIZE_MAX
6022 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6023#endif
6024#ifdef _SC_GETPW_R_SIZE_MAX
6025 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6026#endif
6027#ifdef _SC_ICACHE_ASSOC
6028 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6029#endif
6030#ifdef _SC_ICACHE_BLKSZ
6031 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6032#endif
6033#ifdef _SC_ICACHE_LINESZ
6034 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6035#endif
6036#ifdef _SC_ICACHE_SZ
6037 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6038#endif
Fred Draked86ed291999-12-15 15:34:33 +00006039#ifdef _SC_INF
6040 {"SC_INF", _SC_INF},
6041#endif
Fred Drakec9680921999-12-13 16:37:25 +00006042#ifdef _SC_INT_MAX
6043 {"SC_INT_MAX", _SC_INT_MAX},
6044#endif
6045#ifdef _SC_INT_MIN
6046 {"SC_INT_MIN", _SC_INT_MIN},
6047#endif
6048#ifdef _SC_IOV_MAX
6049 {"SC_IOV_MAX", _SC_IOV_MAX},
6050#endif
Fred Draked86ed291999-12-15 15:34:33 +00006051#ifdef _SC_IP_SECOPTS
6052 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6053#endif
Fred Drakec9680921999-12-13 16:37:25 +00006054#ifdef _SC_JOB_CONTROL
6055 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6056#endif
Fred Draked86ed291999-12-15 15:34:33 +00006057#ifdef _SC_KERN_POINTERS
6058 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6059#endif
6060#ifdef _SC_KERN_SIM
6061 {"SC_KERN_SIM", _SC_KERN_SIM},
6062#endif
Fred Drakec9680921999-12-13 16:37:25 +00006063#ifdef _SC_LINE_MAX
6064 {"SC_LINE_MAX", _SC_LINE_MAX},
6065#endif
6066#ifdef _SC_LOGIN_NAME_MAX
6067 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6068#endif
6069#ifdef _SC_LOGNAME_MAX
6070 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6071#endif
6072#ifdef _SC_LONG_BIT
6073 {"SC_LONG_BIT", _SC_LONG_BIT},
6074#endif
Fred Draked86ed291999-12-15 15:34:33 +00006075#ifdef _SC_MAC
6076 {"SC_MAC", _SC_MAC},
6077#endif
Fred Drakec9680921999-12-13 16:37:25 +00006078#ifdef _SC_MAPPED_FILES
6079 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6080#endif
6081#ifdef _SC_MAXPID
6082 {"SC_MAXPID", _SC_MAXPID},
6083#endif
6084#ifdef _SC_MB_LEN_MAX
6085 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6086#endif
6087#ifdef _SC_MEMLOCK
6088 {"SC_MEMLOCK", _SC_MEMLOCK},
6089#endif
6090#ifdef _SC_MEMLOCK_RANGE
6091 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6092#endif
6093#ifdef _SC_MEMORY_PROTECTION
6094 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6095#endif
6096#ifdef _SC_MESSAGE_PASSING
6097 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6098#endif
Fred Draked86ed291999-12-15 15:34:33 +00006099#ifdef _SC_MMAP_FIXED_ALIGNMENT
6100 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6101#endif
Fred Drakec9680921999-12-13 16:37:25 +00006102#ifdef _SC_MQ_OPEN_MAX
6103 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6104#endif
6105#ifdef _SC_MQ_PRIO_MAX
6106 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6107#endif
Fred Draked86ed291999-12-15 15:34:33 +00006108#ifdef _SC_NACLS_MAX
6109 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6110#endif
Fred Drakec9680921999-12-13 16:37:25 +00006111#ifdef _SC_NGROUPS_MAX
6112 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6113#endif
6114#ifdef _SC_NL_ARGMAX
6115 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6116#endif
6117#ifdef _SC_NL_LANGMAX
6118 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6119#endif
6120#ifdef _SC_NL_MSGMAX
6121 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6122#endif
6123#ifdef _SC_NL_NMAX
6124 {"SC_NL_NMAX", _SC_NL_NMAX},
6125#endif
6126#ifdef _SC_NL_SETMAX
6127 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6128#endif
6129#ifdef _SC_NL_TEXTMAX
6130 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6131#endif
6132#ifdef _SC_NPROCESSORS_CONF
6133 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6134#endif
6135#ifdef _SC_NPROCESSORS_ONLN
6136 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6137#endif
Fred Draked86ed291999-12-15 15:34:33 +00006138#ifdef _SC_NPROC_CONF
6139 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6140#endif
6141#ifdef _SC_NPROC_ONLN
6142 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6143#endif
Fred Drakec9680921999-12-13 16:37:25 +00006144#ifdef _SC_NZERO
6145 {"SC_NZERO", _SC_NZERO},
6146#endif
6147#ifdef _SC_OPEN_MAX
6148 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6149#endif
6150#ifdef _SC_PAGESIZE
6151 {"SC_PAGESIZE", _SC_PAGESIZE},
6152#endif
6153#ifdef _SC_PAGE_SIZE
6154 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6155#endif
6156#ifdef _SC_PASS_MAX
6157 {"SC_PASS_MAX", _SC_PASS_MAX},
6158#endif
6159#ifdef _SC_PHYS_PAGES
6160 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6161#endif
6162#ifdef _SC_PII
6163 {"SC_PII", _SC_PII},
6164#endif
6165#ifdef _SC_PII_INTERNET
6166 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6167#endif
6168#ifdef _SC_PII_INTERNET_DGRAM
6169 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6170#endif
6171#ifdef _SC_PII_INTERNET_STREAM
6172 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6173#endif
6174#ifdef _SC_PII_OSI
6175 {"SC_PII_OSI", _SC_PII_OSI},
6176#endif
6177#ifdef _SC_PII_OSI_CLTS
6178 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6179#endif
6180#ifdef _SC_PII_OSI_COTS
6181 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6182#endif
6183#ifdef _SC_PII_OSI_M
6184 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6185#endif
6186#ifdef _SC_PII_SOCKET
6187 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6188#endif
6189#ifdef _SC_PII_XTI
6190 {"SC_PII_XTI", _SC_PII_XTI},
6191#endif
6192#ifdef _SC_POLL
6193 {"SC_POLL", _SC_POLL},
6194#endif
6195#ifdef _SC_PRIORITIZED_IO
6196 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6197#endif
6198#ifdef _SC_PRIORITY_SCHEDULING
6199 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6200#endif
6201#ifdef _SC_REALTIME_SIGNALS
6202 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6203#endif
6204#ifdef _SC_RE_DUP_MAX
6205 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6206#endif
6207#ifdef _SC_RTSIG_MAX
6208 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6209#endif
6210#ifdef _SC_SAVED_IDS
6211 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6212#endif
6213#ifdef _SC_SCHAR_MAX
6214 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6215#endif
6216#ifdef _SC_SCHAR_MIN
6217 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6218#endif
6219#ifdef _SC_SELECT
6220 {"SC_SELECT", _SC_SELECT},
6221#endif
6222#ifdef _SC_SEMAPHORES
6223 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6224#endif
6225#ifdef _SC_SEM_NSEMS_MAX
6226 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6227#endif
6228#ifdef _SC_SEM_VALUE_MAX
6229 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6230#endif
6231#ifdef _SC_SHARED_MEMORY_OBJECTS
6232 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6233#endif
6234#ifdef _SC_SHRT_MAX
6235 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6236#endif
6237#ifdef _SC_SHRT_MIN
6238 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6239#endif
6240#ifdef _SC_SIGQUEUE_MAX
6241 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6242#endif
6243#ifdef _SC_SIGRT_MAX
6244 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6245#endif
6246#ifdef _SC_SIGRT_MIN
6247 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6248#endif
Fred Draked86ed291999-12-15 15:34:33 +00006249#ifdef _SC_SOFTPOWER
6250 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6251#endif
Fred Drakec9680921999-12-13 16:37:25 +00006252#ifdef _SC_SPLIT_CACHE
6253 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6254#endif
6255#ifdef _SC_SSIZE_MAX
6256 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6257#endif
6258#ifdef _SC_STACK_PROT
6259 {"SC_STACK_PROT", _SC_STACK_PROT},
6260#endif
6261#ifdef _SC_STREAM_MAX
6262 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6263#endif
6264#ifdef _SC_SYNCHRONIZED_IO
6265 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6266#endif
6267#ifdef _SC_THREADS
6268 {"SC_THREADS", _SC_THREADS},
6269#endif
6270#ifdef _SC_THREAD_ATTR_STACKADDR
6271 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6272#endif
6273#ifdef _SC_THREAD_ATTR_STACKSIZE
6274 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6275#endif
6276#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6277 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6278#endif
6279#ifdef _SC_THREAD_KEYS_MAX
6280 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6281#endif
6282#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6283 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6284#endif
6285#ifdef _SC_THREAD_PRIO_INHERIT
6286 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6287#endif
6288#ifdef _SC_THREAD_PRIO_PROTECT
6289 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6290#endif
6291#ifdef _SC_THREAD_PROCESS_SHARED
6292 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6293#endif
6294#ifdef _SC_THREAD_SAFE_FUNCTIONS
6295 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6296#endif
6297#ifdef _SC_THREAD_STACK_MIN
6298 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6299#endif
6300#ifdef _SC_THREAD_THREADS_MAX
6301 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6302#endif
6303#ifdef _SC_TIMERS
6304 {"SC_TIMERS", _SC_TIMERS},
6305#endif
6306#ifdef _SC_TIMER_MAX
6307 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6308#endif
6309#ifdef _SC_TTY_NAME_MAX
6310 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6311#endif
6312#ifdef _SC_TZNAME_MAX
6313 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6314#endif
6315#ifdef _SC_T_IOV_MAX
6316 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6317#endif
6318#ifdef _SC_UCHAR_MAX
6319 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6320#endif
6321#ifdef _SC_UINT_MAX
6322 {"SC_UINT_MAX", _SC_UINT_MAX},
6323#endif
6324#ifdef _SC_UIO_MAXIOV
6325 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6326#endif
6327#ifdef _SC_ULONG_MAX
6328 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6329#endif
6330#ifdef _SC_USHRT_MAX
6331 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6332#endif
6333#ifdef _SC_VERSION
6334 {"SC_VERSION", _SC_VERSION},
6335#endif
6336#ifdef _SC_WORD_BIT
6337 {"SC_WORD_BIT", _SC_WORD_BIT},
6338#endif
6339#ifdef _SC_XBS5_ILP32_OFF32
6340 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6341#endif
6342#ifdef _SC_XBS5_ILP32_OFFBIG
6343 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6344#endif
6345#ifdef _SC_XBS5_LP64_OFF64
6346 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6347#endif
6348#ifdef _SC_XBS5_LPBIG_OFFBIG
6349 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6350#endif
6351#ifdef _SC_XOPEN_CRYPT
6352 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6353#endif
6354#ifdef _SC_XOPEN_ENH_I18N
6355 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6356#endif
6357#ifdef _SC_XOPEN_LEGACY
6358 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6359#endif
6360#ifdef _SC_XOPEN_REALTIME
6361 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6362#endif
6363#ifdef _SC_XOPEN_REALTIME_THREADS
6364 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6365#endif
6366#ifdef _SC_XOPEN_SHM
6367 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6368#endif
6369#ifdef _SC_XOPEN_UNIX
6370 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6371#endif
6372#ifdef _SC_XOPEN_VERSION
6373 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6374#endif
6375#ifdef _SC_XOPEN_XCU_VERSION
6376 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6377#endif
6378#ifdef _SC_XOPEN_XPG2
6379 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6380#endif
6381#ifdef _SC_XOPEN_XPG3
6382 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6383#endif
6384#ifdef _SC_XOPEN_XPG4
6385 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6386#endif
6387};
6388
6389static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006390conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006391{
6392 return conv_confname(arg, valuep, posix_constants_sysconf,
6393 sizeof(posix_constants_sysconf)
6394 / sizeof(struct constdef));
6395}
6396
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006397PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006398"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006399Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006400
6401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006402posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006403{
6404 PyObject *result = NULL;
6405 int name;
6406
6407 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6408 int value;
6409
6410 errno = 0;
6411 value = sysconf(name);
6412 if (value == -1 && errno != 0)
6413 posix_error();
6414 else
Christian Heimes217cfd12007-12-02 14:31:20 +00006415 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00006416 }
6417 return result;
6418}
6419#endif
6420
6421
Fred Drakebec628d1999-12-15 18:31:10 +00006422/* This code is used to ensure that the tables of configuration value names
6423 * are in sorted order as required by conv_confname(), and also to build the
6424 * the exported dictionaries that are used to publish information about the
6425 * names available on the host platform.
6426 *
6427 * Sorting the table at runtime ensures that the table is properly ordered
6428 * when used, even for platforms we're not able to test on. It also makes
6429 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006430 */
Fred Drakebec628d1999-12-15 18:31:10 +00006431
6432static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006433cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006434{
6435 const struct constdef *c1 =
6436 (const struct constdef *) v1;
6437 const struct constdef *c2 =
6438 (const struct constdef *) v2;
6439
6440 return strcmp(c1->name, c2->name);
6441}
6442
6443static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006444setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006445 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006446{
Fred Drakebec628d1999-12-15 18:31:10 +00006447 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006448 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006449
6450 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6451 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006452 if (d == NULL)
6453 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006454
Barry Warsaw3155db32000-04-13 15:20:40 +00006455 for (i=0; i < tablesize; ++i) {
Christian Heimes217cfd12007-12-02 14:31:20 +00006456 PyObject *o = PyLong_FromLong(table[i].value);
Barry Warsaw3155db32000-04-13 15:20:40 +00006457 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6458 Py_XDECREF(o);
6459 Py_DECREF(d);
6460 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006461 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006462 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006463 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006464 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006465}
6466
Fred Drakebec628d1999-12-15 18:31:10 +00006467/* Return -1 on failure, 0 on success. */
6468static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006469setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006470{
6471#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006472 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006473 sizeof(posix_constants_pathconf)
6474 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006475 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006476 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006477#endif
6478#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006479 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006480 sizeof(posix_constants_confstr)
6481 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006482 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006483 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006484#endif
6485#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006486 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006487 sizeof(posix_constants_sysconf)
6488 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006489 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006490 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006491#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006492 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006493}
Fred Draked86ed291999-12-15 15:34:33 +00006494
6495
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006496PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006497"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006498Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006499in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006500
6501static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006502posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006503{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006504 abort();
6505 /*NOTREACHED*/
6506 Py_FatalError("abort() called from Python code didn't abort!");
6507 return NULL;
6508}
Fred Drakebec628d1999-12-15 18:31:10 +00006509
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006510#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006511PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00006512"startfile(filepath [, operation]) - Start a file with its associated\n\
6513application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006514\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00006515When \"operation\" is not specified or \"open\", this acts like\n\
6516double-clicking the file in Explorer, or giving the file name as an\n\
6517argument to the DOS \"start\" command: the file is opened with whatever\n\
6518application (if any) its extension is associated.\n\
6519When another \"operation\" is given, it specifies what should be done with\n\
6520the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006521\n\
6522startfile returns as soon as the associated application is launched.\n\
6523There is no option to wait for the application to close, and no way\n\
6524to retrieve the application's exit status.\n\
6525\n\
6526The filepath is relative to the current directory. If you want to use\n\
6527an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006528the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006529
6530static PyObject *
6531win32_startfile(PyObject *self, PyObject *args)
6532{
6533 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00006534 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006535 HINSTANCE rc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006536#ifdef Py_WIN_WIDE_FILENAMES
6537 if (unicode_file_names()) {
6538 PyObject *unipath, *woperation = NULL;
6539 if (!PyArg_ParseTuple(args, "U|s:startfile",
6540 &unipath, &operation)) {
6541 PyErr_Clear();
6542 goto normal;
6543 }
6544
6545
6546 if (operation) {
6547 woperation = PyUnicode_DecodeASCII(operation,
6548 strlen(operation), NULL);
6549 if (!woperation) {
6550 PyErr_Clear();
6551 operation = NULL;
6552 goto normal;
6553 }
6554 }
6555
6556 Py_BEGIN_ALLOW_THREADS
6557 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6558 PyUnicode_AS_UNICODE(unipath),
6559 NULL, NULL, SW_SHOWNORMAL);
6560 Py_END_ALLOW_THREADS
6561
6562 Py_XDECREF(woperation);
6563 if (rc <= (HINSTANCE)32) {
6564 PyObject *errval = win32_error_unicode("startfile",
6565 PyUnicode_AS_UNICODE(unipath));
6566 return errval;
6567 }
6568 Py_INCREF(Py_None);
6569 return Py_None;
6570 }
6571#endif
6572
6573normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00006574 if (!PyArg_ParseTuple(args, "et|s:startfile",
6575 Py_FileSystemDefaultEncoding, &filepath,
6576 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00006577 return NULL;
6578 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00006579 rc = ShellExecute((HWND)0, operation, filepath,
6580 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006581 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00006582 if (rc <= (HINSTANCE)32) {
6583 PyObject *errval = win32_error("startfile", filepath);
6584 PyMem_Free(filepath);
6585 return errval;
6586 }
6587 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006588 Py_INCREF(Py_None);
6589 return Py_None;
6590}
6591#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006592
Martin v. Löwis438b5342002-12-27 10:16:42 +00006593#ifdef HAVE_GETLOADAVG
6594PyDoc_STRVAR(posix_getloadavg__doc__,
6595"getloadavg() -> (float, float, float)\n\n\
6596Return the number of processes in the system run queue averaged over\n\
6597the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6598was unobtainable");
6599
6600static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006601posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006602{
6603 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006604 if (getloadavg(loadavg, 3)!=3) {
6605 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6606 return NULL;
6607 } else
6608 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6609}
6610#endif
6611
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006612#ifdef MS_WINDOWS
6613
6614PyDoc_STRVAR(win32_urandom__doc__,
6615"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006616Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006617
6618typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6619 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6620 DWORD dwFlags );
6621typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6622 BYTE *pbBuffer );
6623
6624static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00006625/* This handle is never explicitly released. Instead, the operating
6626 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006627static HCRYPTPROV hCryptProv = 0;
6628
Tim Peters4ad82172004-08-30 17:02:04 +00006629static PyObject*
6630win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006631{
Tim Petersd3115382004-08-30 17:36:46 +00006632 int howMany;
6633 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006634
Tim Peters4ad82172004-08-30 17:02:04 +00006635 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00006636 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00006637 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00006638 if (howMany < 0)
6639 return PyErr_Format(PyExc_ValueError,
6640 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006641
Tim Peters4ad82172004-08-30 17:02:04 +00006642 if (hCryptProv == 0) {
6643 HINSTANCE hAdvAPI32 = NULL;
6644 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006645
Tim Peters4ad82172004-08-30 17:02:04 +00006646 /* Obtain handle to the DLL containing CryptoAPI
6647 This should not fail */
6648 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6649 if(hAdvAPI32 == NULL)
6650 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006651
Tim Peters4ad82172004-08-30 17:02:04 +00006652 /* Obtain pointers to the CryptoAPI functions
6653 This will fail on some early versions of Win95 */
6654 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6655 hAdvAPI32,
6656 "CryptAcquireContextA");
6657 if (pCryptAcquireContext == NULL)
6658 return PyErr_Format(PyExc_NotImplementedError,
6659 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006660
Tim Peters4ad82172004-08-30 17:02:04 +00006661 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6662 hAdvAPI32, "CryptGenRandom");
Thomas Wouters89f507f2006-12-13 04:49:30 +00006663 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00006664 return PyErr_Format(PyExc_NotImplementedError,
6665 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006666
Tim Peters4ad82172004-08-30 17:02:04 +00006667 /* Acquire context */
6668 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
6669 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
6670 return win32_error("CryptAcquireContext", NULL);
6671 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006672
Tim Peters4ad82172004-08-30 17:02:04 +00006673 /* Allocate bytes */
Christian Heimes72b710a2008-05-26 13:28:38 +00006674 result = PyBytes_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00006675 if (result != NULL) {
6676 /* Get random data */
Amaury Forgeot d'Arca05ada32008-07-21 21:13:14 +00006677 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00006678 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Christian Heimes72b710a2008-05-26 13:28:38 +00006679 PyBytes_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00006680 Py_DECREF(result);
6681 return win32_error("CryptGenRandom", NULL);
6682 }
Tim Peters4ad82172004-08-30 17:02:04 +00006683 }
Tim Petersd3115382004-08-30 17:36:46 +00006684 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006685}
6686#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00006687
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006688PyDoc_STRVAR(device_encoding__doc__,
6689"device_encoding(fd) -> str\n\n\
6690Return a string describing the encoding of the device\n\
6691if the output is a terminal; else return None.");
6692
6693static PyObject *
6694device_encoding(PyObject *self, PyObject *args)
6695{
6696 int fd;
6697 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
6698 return NULL;
6699 if (!isatty(fd)) {
6700 Py_INCREF(Py_None);
6701 return Py_None;
6702 }
6703#if defined(MS_WINDOWS) || defined(MS_WIN64)
6704 if (fd == 0) {
6705 char buf[100];
6706 sprintf(buf, "cp%d", GetConsoleCP());
6707 return PyUnicode_FromString(buf);
6708 }
6709 if (fd == 1 || fd == 2) {
6710 char buf[100];
6711 sprintf(buf, "cp%d", GetConsoleOutputCP());
6712 return PyUnicode_FromString(buf);
6713 }
6714#elif defined(CODESET)
6715 {
6716 char *codeset = nl_langinfo(CODESET);
6717 if (codeset)
6718 return PyUnicode_FromString(codeset);
6719 }
6720#endif
6721 Py_INCREF(Py_None);
6722 return Py_None;
6723}
6724
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006725#ifdef __VMS
6726/* Use openssl random routine */
6727#include <openssl/rand.h>
6728PyDoc_STRVAR(vms_urandom__doc__,
6729"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006730Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006731
6732static PyObject*
6733vms_urandom(PyObject *self, PyObject *args)
6734{
6735 int howMany;
6736 PyObject* result;
6737
6738 /* Read arguments */
6739 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
6740 return NULL;
6741 if (howMany < 0)
6742 return PyErr_Format(PyExc_ValueError,
6743 "negative argument not allowed");
6744
6745 /* Allocate bytes */
Christian Heimes72b710a2008-05-26 13:28:38 +00006746 result = PyBytes_FromStringAndSize(NULL, howMany);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006747 if (result != NULL) {
6748 /* Get random data */
6749 if (RAND_pseudo_bytes((unsigned char*)
Christian Heimes72b710a2008-05-26 13:28:38 +00006750 PyBytes_AS_STRING(result),
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006751 howMany) < 0) {
6752 Py_DECREF(result);
6753 return PyErr_Format(PyExc_ValueError,
6754 "RAND_pseudo_bytes");
6755 }
6756 }
6757 return result;
6758}
6759#endif
6760
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006761static PyMethodDef posix_methods[] = {
6762 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6763#ifdef HAVE_TTYNAME
6764 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6765#endif
6766 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00006767#ifdef HAVE_CHFLAGS
6768 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
6769#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006770 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00006771#ifdef HAVE_FCHMOD
6772 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
6773#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006774#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006775 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006776#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00006777#ifdef HAVE_LCHMOD
6778 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
6779#endif /* HAVE_LCHMOD */
6780#ifdef HAVE_FCHOWN
6781 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
6782#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00006783#ifdef HAVE_LCHFLAGS
6784 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
6785#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006786#ifdef HAVE_LCHOWN
6787 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6788#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006789#ifdef HAVE_CHROOT
6790 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6791#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006792#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006793 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006794#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006795#ifdef HAVE_GETCWD
Guido van Rossumf0af3e32008-10-02 18:55:37 +00006796 {"getcwd", (PyCFunction)posix_getcwd_unicode,
6797 METH_NOARGS, posix_getcwd__doc__},
6798 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
6799 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006800#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006801#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006802 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006803#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006804 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6805 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6806 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006807#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006808 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006809#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006810#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006811 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006812#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006813 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6814 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6815 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006816 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006817#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006818 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006819#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006820#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006821 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006822#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006823 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006824#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00006825 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006826#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006827 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6828 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6829 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006830#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00006831 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006832#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006833 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006834#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006835 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6836 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006837#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006838#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006839 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6840 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006841#if defined(PYOS_OS2)
6842 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
6843 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
6844#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00006845#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006846#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00006847 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006848#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006849#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00006850 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006851#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006852#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00006853 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006854#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006855#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00006856 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00006857#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006858#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006859 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006860#endif /* HAVE_GETEGID */
6861#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006862 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006863#endif /* HAVE_GETEUID */
6864#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006865 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006866#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006867#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00006868 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00006869#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00006870 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006871#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006872 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006873#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006874#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00006875 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006876#endif /* HAVE_GETPPID */
6877#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006878 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006879#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006880#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00006881 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00006882#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006883#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006884 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006885#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006886#ifdef HAVE_KILLPG
6887 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6888#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006889#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006890 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006891#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00006892#ifdef MS_WINDOWS
6893 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
6894#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006895#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006896 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006897#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006898#ifdef HAVE_SETEUID
6899 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6900#endif /* HAVE_SETEUID */
6901#ifdef HAVE_SETEGID
6902 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6903#endif /* HAVE_SETEGID */
6904#ifdef HAVE_SETREUID
6905 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6906#endif /* HAVE_SETREUID */
6907#ifdef HAVE_SETREGID
6908 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6909#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006910#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006911 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006912#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006913#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006914 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006915#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006916#ifdef HAVE_GETPGID
6917 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6918#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006919#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006920 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006921#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006922#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00006923 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006924#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006925#ifdef HAVE_WAIT3
6926 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
6927#endif /* HAVE_WAIT3 */
6928#ifdef HAVE_WAIT4
6929 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
6930#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00006931#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006932 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006933#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006934#ifdef HAVE_GETSID
6935 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
6936#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006937#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00006938 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006939#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006940#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006941 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006942#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006943#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006944 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006945#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006946#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006947 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006948#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006949 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6950 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Christian Heimesfdab48e2008-01-20 09:06:41 +00006951 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006952 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006953 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6954 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6955 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6956 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6957 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6958 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006959 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006960#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00006961 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006962#endif
6963#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006964 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006965#endif
Neal Norwitz11690112002-07-30 01:08:28 +00006966#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006967 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6968#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006969#ifdef HAVE_DEVICE_MACROS
6970 {"major", posix_major, METH_VARARGS, posix_major__doc__},
6971 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
6972 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
6973#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006974#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006975 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006976#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006977#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006978 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006979#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006980#ifdef HAVE_UNSETENV
6981 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6982#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006983 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00006984#ifdef HAVE_FCHDIR
6985 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6986#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006987#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006988 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006989#endif
6990#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006991 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006992#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006993#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006994#ifdef WCOREDUMP
6995 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6996#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006997#ifdef WIFCONTINUED
6998 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6999#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007000#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007001 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007002#endif /* WIFSTOPPED */
7003#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007004 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007005#endif /* WIFSIGNALED */
7006#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007007 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007008#endif /* WIFEXITED */
7009#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007010 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007011#endif /* WEXITSTATUS */
7012#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007013 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007014#endif /* WTERMSIG */
7015#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007016 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007017#endif /* WSTOPSIG */
7018#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007019#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007020 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007021#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007022#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007023 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007024#endif
Fred Drakec9680921999-12-13 16:37:25 +00007025#ifdef HAVE_CONFSTR
7026 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7027#endif
7028#ifdef HAVE_SYSCONF
7029 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7030#endif
7031#ifdef HAVE_FPATHCONF
7032 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7033#endif
7034#ifdef HAVE_PATHCONF
7035 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7036#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007037 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007038#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007039 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7040#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007041#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007042 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007043#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007044 #ifdef MS_WINDOWS
7045 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7046 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007047 #ifdef __VMS
7048 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
7049 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007050 {NULL, NULL} /* Sentinel */
7051};
7052
7053
Barry Warsaw4a342091996-12-19 23:50:02 +00007054static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007055ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007056{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007057 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007058}
7059
Guido van Rossumd48f2521997-12-05 22:19:34 +00007060#if defined(PYOS_OS2)
7061/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007062static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007063{
7064 APIRET rc;
7065 ULONG values[QSV_MAX+1];
7066 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007067 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007068
7069 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007070 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007071 Py_END_ALLOW_THREADS
7072
7073 if (rc != NO_ERROR) {
7074 os2_error(rc);
7075 return -1;
7076 }
7077
Fred Drake4d1e64b2002-04-15 19:40:07 +00007078 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7079 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7080 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7081 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7082 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7083 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7084 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007085
7086 switch (values[QSV_VERSION_MINOR]) {
7087 case 0: ver = "2.00"; break;
7088 case 10: ver = "2.10"; break;
7089 case 11: ver = "2.11"; break;
7090 case 30: ver = "3.00"; break;
7091 case 40: ver = "4.00"; break;
7092 case 50: ver = "5.00"; break;
7093 default:
Tim Peters885d4572001-11-28 20:27:42 +00007094 PyOS_snprintf(tmp, sizeof(tmp),
7095 "%d-%d", values[QSV_VERSION_MAJOR],
7096 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007097 ver = &tmp[0];
7098 }
7099
7100 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007101 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007102 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007103
7104 /* Add Indicator of Which Drive was Used to Boot the System */
7105 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7106 tmp[1] = ':';
7107 tmp[2] = '\0';
7108
Fred Drake4d1e64b2002-04-15 19:40:07 +00007109 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007110}
7111#endif
7112
Barry Warsaw4a342091996-12-19 23:50:02 +00007113static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007114all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007115{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007116#ifdef F_OK
7117 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007118#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007119#ifdef R_OK
7120 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007121#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007122#ifdef W_OK
7123 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007124#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007125#ifdef X_OK
7126 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007127#endif
Fred Drakec9680921999-12-13 16:37:25 +00007128#ifdef NGROUPS_MAX
7129 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7130#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007131#ifdef TMP_MAX
7132 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7133#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007134#ifdef WCONTINUED
7135 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7136#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007137#ifdef WNOHANG
7138 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007139#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007140#ifdef WUNTRACED
7141 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7142#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007143#ifdef O_RDONLY
7144 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7145#endif
7146#ifdef O_WRONLY
7147 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7148#endif
7149#ifdef O_RDWR
7150 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7151#endif
7152#ifdef O_NDELAY
7153 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7154#endif
7155#ifdef O_NONBLOCK
7156 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7157#endif
7158#ifdef O_APPEND
7159 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7160#endif
7161#ifdef O_DSYNC
7162 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7163#endif
7164#ifdef O_RSYNC
7165 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7166#endif
7167#ifdef O_SYNC
7168 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7169#endif
7170#ifdef O_NOCTTY
7171 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7172#endif
7173#ifdef O_CREAT
7174 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7175#endif
7176#ifdef O_EXCL
7177 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7178#endif
7179#ifdef O_TRUNC
7180 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7181#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007182#ifdef O_BINARY
7183 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7184#endif
7185#ifdef O_TEXT
7186 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7187#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007188#ifdef O_LARGEFILE
7189 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7190#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007191#ifdef O_SHLOCK
7192 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7193#endif
7194#ifdef O_EXLOCK
7195 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7196#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007197
Tim Peters5aa91602002-01-30 05:46:57 +00007198/* MS Windows */
7199#ifdef O_NOINHERIT
7200 /* Don't inherit in child processes. */
7201 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7202#endif
7203#ifdef _O_SHORT_LIVED
7204 /* Optimize for short life (keep in memory). */
7205 /* MS forgot to define this one with a non-underscore form too. */
7206 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7207#endif
7208#ifdef O_TEMPORARY
7209 /* Automatically delete when last handle is closed. */
7210 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7211#endif
7212#ifdef O_RANDOM
7213 /* Optimize for random access. */
7214 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7215#endif
7216#ifdef O_SEQUENTIAL
7217 /* Optimize for sequential access. */
7218 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7219#endif
7220
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007221/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00007222#ifdef O_ASYNC
7223 /* Send a SIGIO signal whenever input or output
7224 becomes available on file descriptor */
7225 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
7226#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007227#ifdef O_DIRECT
7228 /* Direct disk access. */
7229 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7230#endif
7231#ifdef O_DIRECTORY
7232 /* Must be a directory. */
7233 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7234#endif
7235#ifdef O_NOFOLLOW
7236 /* Do not follow links. */
7237 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7238#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00007239#ifdef O_NOATIME
7240 /* Do not update the access time. */
7241 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
7242#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007243
Barry Warsaw5676bd12003-01-07 20:57:09 +00007244 /* These come from sysexits.h */
7245#ifdef EX_OK
7246 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007247#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007248#ifdef EX_USAGE
7249 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007250#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007251#ifdef EX_DATAERR
7252 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007253#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007254#ifdef EX_NOINPUT
7255 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007256#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007257#ifdef EX_NOUSER
7258 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007259#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007260#ifdef EX_NOHOST
7261 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007262#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007263#ifdef EX_UNAVAILABLE
7264 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007265#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007266#ifdef EX_SOFTWARE
7267 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007268#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007269#ifdef EX_OSERR
7270 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007271#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007272#ifdef EX_OSFILE
7273 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007274#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007275#ifdef EX_CANTCREAT
7276 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007277#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007278#ifdef EX_IOERR
7279 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007280#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007281#ifdef EX_TEMPFAIL
7282 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007283#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007284#ifdef EX_PROTOCOL
7285 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007286#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007287#ifdef EX_NOPERM
7288 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007289#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007290#ifdef EX_CONFIG
7291 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007292#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007293#ifdef EX_NOTFOUND
7294 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007295#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007296
Guido van Rossum246bc171999-02-01 23:54:31 +00007297#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007298#if defined(PYOS_OS2) && defined(PYCC_GCC)
7299 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7300 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7301 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7302 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7303 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7304 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7305 if (ins(d, "P_PM", (long)P_PM)) return -1;
7306 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7307 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7308 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7309 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7310 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7311 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7312 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7313 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7314 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7315 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7316 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7317 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7318 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7319#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007320 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7321 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7322 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7323 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7324 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007325#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007326#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007327
Guido van Rossumd48f2521997-12-05 22:19:34 +00007328#if defined(PYOS_OS2)
7329 if (insertvalues(d)) return -1;
7330#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007331 return 0;
7332}
7333
7334
Tim Peters5aa91602002-01-30 05:46:57 +00007335#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007336#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007337#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007338
7339#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007340#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007341#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007342
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007343#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00007344#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007345#define MODNAME "posix"
7346#endif
7347
Martin v. Löwis1a214512008-06-11 05:26:20 +00007348static struct PyModuleDef posixmodule = {
7349 PyModuleDef_HEAD_INIT,
7350 MODNAME,
7351 posix__doc__,
7352 -1,
7353 posix_methods,
7354 NULL,
7355 NULL,
7356 NULL,
7357 NULL
7358};
7359
7360
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007361PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007362INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007363{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007364 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007365
Martin v. Löwis1a214512008-06-11 05:26:20 +00007366 m = PyModule_Create(&posixmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00007367 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007368 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007369
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007370 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007371 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007372 Py_XINCREF(v);
7373 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007374 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00007375 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007376
Fred Drake4d1e64b2002-04-15 19:40:07 +00007377 if (all_ins(m))
Martin v. Löwis1a214512008-06-11 05:26:20 +00007378 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00007379
Fred Drake4d1e64b2002-04-15 19:40:07 +00007380 if (setup_confname_tables(m))
Martin v. Löwis1a214512008-06-11 05:26:20 +00007381 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00007382
Fred Drake4d1e64b2002-04-15 19:40:07 +00007383 Py_INCREF(PyExc_OSError);
7384 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007385
Guido van Rossumb3d39562000-01-31 18:41:26 +00007386#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007387 if (posix_putenv_garbage == NULL)
7388 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007389#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007390
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007391 if (!initialized) {
7392 stat_result_desc.name = MODNAME ".stat_result";
7393 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7394 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7395 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7396 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7397 structseq_new = StatResultType.tp_new;
7398 StatResultType.tp_new = statresult_new;
7399
7400 statvfs_result_desc.name = MODNAME ".statvfs_result";
7401 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
7402 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007403 Py_INCREF((PyObject*) &StatResultType);
7404 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007405 Py_INCREF((PyObject*) &StatVFSResultType);
7406 PyModule_AddObject(m, "statvfs_result",
7407 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007408 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007409
7410#ifdef __APPLE__
7411 /*
7412 * Step 2 of weak-linking support on Mac OS X.
7413 *
7414 * The code below removes functions that are not available on the
7415 * currently active platform.
7416 *
7417 * This block allow one to use a python binary that was build on
7418 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7419 * OSX 10.4.
7420 */
7421#ifdef HAVE_FSTATVFS
7422 if (fstatvfs == NULL) {
7423 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007424 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007425 }
7426 }
7427#endif /* HAVE_FSTATVFS */
7428
7429#ifdef HAVE_STATVFS
7430 if (statvfs == NULL) {
7431 if (PyObject_DelAttrString(m, "statvfs") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007432 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007433 }
7434 }
7435#endif /* HAVE_STATVFS */
7436
7437# ifdef HAVE_LCHOWN
7438 if (lchown == NULL) {
7439 if (PyObject_DelAttrString(m, "lchown") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007440 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007441 }
7442 }
7443#endif /* HAVE_LCHOWN */
7444
7445
7446#endif /* __APPLE__ */
Martin v. Löwis1a214512008-06-11 05:26:20 +00007447 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007448
Guido van Rossumb6775db1994-08-01 11:34:53 +00007449}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007450
7451#ifdef __cplusplus
7452}
7453#endif