blob: f183d868327e867d232859aad77d36e78d107615 [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') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000428 PyObject *v = PyString_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') */
434 PyObject *v = PyString_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.
479 (_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
506/* Function suitable for O& conversion */
507static int
508convert_to_unicode(PyObject *arg, void* _param)
509{
510 PyObject **param = (PyObject**)_param;
511 if (PyUnicode_CheckExact(arg)) {
512 Py_INCREF(arg);
513 *param = arg;
514 }
515 else if (PyUnicode_Check(arg)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000516 /* For a Unicode subtype that's not a Unicode object,
517 return a true Unicode object with the same data. */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000518 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
519 PyUnicode_GET_SIZE(arg));
520 return *param != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000521 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000522 else
523 *param = PyUnicode_FromEncodedObject(arg,
524 Py_FileSystemDefaultEncoding,
525 "strict");
526 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000527}
528
529#endif /* Py_WIN_WIDE_FILENAMES */
530
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000531#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000532
Guido van Rossumd48f2521997-12-05 22:19:34 +0000533#if defined(PYOS_OS2)
534/**********************************************************************
535 * Helper Function to Trim and Format OS/2 Messages
536 **********************************************************************/
537 static void
538os2_formatmsg(char *msgbuf, int msglen, char *reason)
539{
540 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
541
542 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
543 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
544
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000545 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000546 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
547 }
548
549 /* Add Optional Reason Text */
550 if (reason) {
551 strcat(msgbuf, " : ");
552 strcat(msgbuf, reason);
553 }
554}
555
556/**********************************************************************
557 * Decode an OS/2 Operating System Error Code
558 *
559 * A convenience function to lookup an OS/2 error code and return a
560 * text message we can use to raise a Python exception.
561 *
562 * Notes:
563 * The messages for errors returned from the OS/2 kernel reside in
564 * the file OSO001.MSG in the \OS2 directory hierarchy.
565 *
566 **********************************************************************/
567 static char *
568os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
569{
570 APIRET rc;
571 ULONG msglen;
572
573 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
574 Py_BEGIN_ALLOW_THREADS
575 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
576 errorcode, "oso001.msg", &msglen);
577 Py_END_ALLOW_THREADS
578
579 if (rc == NO_ERROR)
580 os2_formatmsg(msgbuf, msglen, reason);
581 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000582 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000583 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000584
585 return msgbuf;
586}
587
588/* Set an OS/2-specific error and return NULL. OS/2 kernel
589 errors are not in a global variable e.g. 'errno' nor are
590 they congruent with posix error numbers. */
591
592static PyObject * os2_error(int code)
593{
594 char text[1024];
595 PyObject *v;
596
597 os2_strerror(text, sizeof(text), code, "");
598
599 v = Py_BuildValue("(is)", code, text);
600 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000601 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000602 Py_DECREF(v);
603 }
604 return NULL; /* Signal to Python that an Exception is Pending */
605}
606
607#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000608
609/* POSIX generic methods */
610
Barry Warsaw53699e91996-12-10 23:23:01 +0000611static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000612posix_fildes(PyObject *fdobj, int (*func)(int))
613{
614 int fd;
615 int res;
616 fd = PyObject_AsFileDescriptor(fdobj);
617 if (fd < 0)
618 return NULL;
619 Py_BEGIN_ALLOW_THREADS
620 res = (*func)(fd);
621 Py_END_ALLOW_THREADS
622 if (res < 0)
623 return posix_error();
624 Py_INCREF(Py_None);
625 return Py_None;
626}
Guido van Rossum21142a01999-01-08 21:05:37 +0000627
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000628#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000629static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000630unicode_file_names(void)
631{
632 static int canusewide = -1;
633 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000634 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000635 the Windows NT family. */
636 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
637 }
638 return canusewide;
639}
640#endif
Tim Peters11b23062003-04-23 02:39:17 +0000641
Guido van Rossum21142a01999-01-08 21:05:37 +0000642static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000643posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000644{
Mark Hammondef8b6542001-05-13 08:04:26 +0000645 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000646 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000647 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000648 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000649 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000650 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000651 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000652 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000653 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000654 return posix_error_with_allocated_filename(path1);
655 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000656 Py_INCREF(Py_None);
657 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000658}
659
Barry Warsaw53699e91996-12-10 23:23:01 +0000660static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000661posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000662 char *format,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000663 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664{
Mark Hammondef8b6542001-05-13 08:04:26 +0000665 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000666 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000667 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000668 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000669 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000670 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000671 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000672 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000673 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000674 PyMem_Free(path1);
675 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000676 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000677 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000678 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000679 Py_INCREF(Py_None);
680 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000681}
682
Thomas Wouters477c8d52006-05-27 19:21:47 +0000683#ifdef Py_WIN_WIDE_FILENAMES
684static PyObject*
685win32_1str(PyObject* args, char* func,
686 char* format, BOOL (__stdcall *funcA)(LPCSTR),
687 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
688{
689 PyObject *uni;
690 char *ansi;
691 BOOL result;
692 if (unicode_file_names()) {
693 if (!PyArg_ParseTuple(args, wformat, &uni))
694 PyErr_Clear();
695 else {
696 Py_BEGIN_ALLOW_THREADS
697 result = funcW(PyUnicode_AsUnicode(uni));
698 Py_END_ALLOW_THREADS
699 if (!result)
700 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
701 Py_INCREF(Py_None);
702 return Py_None;
703 }
704 }
705 if (!PyArg_ParseTuple(args, format, &ansi))
706 return NULL;
707 Py_BEGIN_ALLOW_THREADS
708 result = funcA(ansi);
709 Py_END_ALLOW_THREADS
710 if (!result)
711 return win32_error(func, ansi);
712 Py_INCREF(Py_None);
713 return Py_None;
714
715}
716
717/* This is a reimplementation of the C library's chdir function,
718 but one that produces Win32 errors instead of DOS error codes.
719 chdir is essentially a wrapper around SetCurrentDirectory; however,
720 it also needs to set "magic" environment variables indicating
721 the per-drive current directory, which are of the form =<drive>: */
722BOOL __stdcall
723win32_chdir(LPCSTR path)
724{
725 char new_path[MAX_PATH+1];
726 int result;
727 char env[4] = "=x:";
728
729 if(!SetCurrentDirectoryA(path))
730 return FALSE;
731 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
732 if (!result)
733 return FALSE;
734 /* In the ANSI API, there should not be any paths longer
735 than MAX_PATH. */
736 assert(result <= MAX_PATH+1);
737 if (strncmp(new_path, "\\\\", 2) == 0 ||
738 strncmp(new_path, "//", 2) == 0)
739 /* UNC path, nothing to do. */
740 return TRUE;
741 env[1] = new_path[0];
742 return SetEnvironmentVariableA(env, new_path);
743}
744
745/* The Unicode version differs from the ANSI version
746 since the current directory might exceed MAX_PATH characters */
747BOOL __stdcall
748win32_wchdir(LPCWSTR path)
749{
750 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
751 int result;
752 wchar_t env[4] = L"=x:";
753
754 if(!SetCurrentDirectoryW(path))
755 return FALSE;
756 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
757 if (!result)
758 return FALSE;
759 if (result > MAX_PATH+1) {
760 new_path = malloc(result);
761 if (!new_path) {
762 SetLastError(ERROR_OUTOFMEMORY);
763 return FALSE;
764 }
765 }
766 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
767 wcsncmp(new_path, L"//", 2) == 0)
768 /* UNC path, nothing to do. */
769 return TRUE;
770 env[1] = new_path[0];
771 result = SetEnvironmentVariableW(env, new_path);
772 if (new_path != _new_path)
773 free(new_path);
774 return result;
775}
776#endif
777
Martin v. Löwis14694662006-02-03 12:54:16 +0000778#ifdef MS_WINDOWS
779/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
780 - time stamps are restricted to second resolution
781 - file modification times suffer from forth-and-back conversions between
782 UTC and local time
783 Therefore, we implement our own stat, based on the Win32 API directly.
784*/
785#define HAVE_STAT_NSEC 1
786
787struct win32_stat{
788 int st_dev;
789 __int64 st_ino;
790 unsigned short st_mode;
791 int st_nlink;
792 int st_uid;
793 int st_gid;
794 int st_rdev;
795 __int64 st_size;
796 int st_atime;
797 int st_atime_nsec;
798 int st_mtime;
799 int st_mtime_nsec;
800 int st_ctime;
801 int st_ctime_nsec;
802};
803
804static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
805
806static void
807FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
808{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000809 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
810 /* Cannot simply cast and dereference in_ptr,
811 since it might not be aligned properly */
812 __int64 in;
813 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000814 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
815 /* XXX Win32 supports time stamps past 2038; we currently don't */
816 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
817}
818
Thomas Wouters477c8d52006-05-27 19:21:47 +0000819static void
820time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
821{
822 /* XXX endianness */
823 __int64 out;
824 out = time_in + secs_between_epochs;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000825 out = out * 10000000 + nsec_in / 100;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000826 memcpy(out_ptr, &out, sizeof(out));
827}
828
Martin v. Löwis14694662006-02-03 12:54:16 +0000829/* Below, we *know* that ugo+r is 0444 */
830#if _S_IREAD != 0400
831#error Unsupported C library
832#endif
833static int
834attributes_to_mode(DWORD attr)
835{
836 int m = 0;
837 if (attr & FILE_ATTRIBUTE_DIRECTORY)
838 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
839 else
840 m |= _S_IFREG;
841 if (attr & FILE_ATTRIBUTE_READONLY)
842 m |= 0444;
843 else
844 m |= 0666;
845 return m;
846}
847
848static int
849attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
850{
851 memset(result, 0, sizeof(*result));
852 result->st_mode = attributes_to_mode(info->dwFileAttributes);
853 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
854 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
855 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
856 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
857
858 return 0;
859}
860
Thomas Wouters89f507f2006-12-13 04:49:30 +0000861/* Emulate GetFileAttributesEx[AW] on Windows 95 */
862static int checked = 0;
863static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
864static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
865static void
866check_gfax()
867{
868 HINSTANCE hKernel32;
869 if (checked)
870 return;
871 checked = 1;
872 hKernel32 = GetModuleHandle("KERNEL32");
873 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
874 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
875}
876
Guido van Rossumd8faa362007-04-27 19:54:29 +0000877static BOOL
878attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
879{
880 HANDLE hFindFile;
881 WIN32_FIND_DATAA FileData;
882 hFindFile = FindFirstFileA(pszFile, &FileData);
883 if (hFindFile == INVALID_HANDLE_VALUE)
884 return FALSE;
885 FindClose(hFindFile);
886 pfad->dwFileAttributes = FileData.dwFileAttributes;
887 pfad->ftCreationTime = FileData.ftCreationTime;
888 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
889 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
890 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
891 pfad->nFileSizeLow = FileData.nFileSizeLow;
892 return TRUE;
893}
894
895static BOOL
896attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
897{
898 HANDLE hFindFile;
899 WIN32_FIND_DATAW FileData;
900 hFindFile = FindFirstFileW(pszFile, &FileData);
901 if (hFindFile == INVALID_HANDLE_VALUE)
902 return FALSE;
903 FindClose(hFindFile);
904 pfad->dwFileAttributes = FileData.dwFileAttributes;
905 pfad->ftCreationTime = FileData.ftCreationTime;
906 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
907 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
908 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
909 pfad->nFileSizeLow = FileData.nFileSizeLow;
910 return TRUE;
911}
912
Thomas Wouters89f507f2006-12-13 04:49:30 +0000913static BOOL WINAPI
914Py_GetFileAttributesExA(LPCSTR pszFile,
915 GET_FILEEX_INFO_LEVELS level,
916 LPVOID pv)
917{
918 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000919 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
920 /* First try to use the system's implementation, if that is
921 available and either succeeds to gives an error other than
922 that it isn't implemented. */
923 check_gfax();
924 if (gfaxa) {
925 result = gfaxa(pszFile, level, pv);
926 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
927 return result;
928 }
929 /* It's either not present, or not implemented.
930 Emulate using FindFirstFile. */
931 if (level != GetFileExInfoStandard) {
932 SetLastError(ERROR_INVALID_PARAMETER);
933 return FALSE;
934 }
935 /* Use GetFileAttributes to validate that the file name
936 does not contain wildcards (which FindFirstFile would
937 accept). */
938 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
939 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000940 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000941}
942
943static BOOL WINAPI
944Py_GetFileAttributesExW(LPCWSTR pszFile,
945 GET_FILEEX_INFO_LEVELS level,
946 LPVOID pv)
947{
948 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000949 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
950 /* First try to use the system's implementation, if that is
951 available and either succeeds to gives an error other than
952 that it isn't implemented. */
953 check_gfax();
954 if (gfaxa) {
955 result = gfaxw(pszFile, level, pv);
956 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
957 return result;
958 }
959 /* It's either not present, or not implemented.
960 Emulate using FindFirstFile. */
961 if (level != GetFileExInfoStandard) {
962 SetLastError(ERROR_INVALID_PARAMETER);
963 return FALSE;
964 }
965 /* Use GetFileAttributes to validate that the file name
966 does not contain wildcards (which FindFirstFile would
967 accept). */
968 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
969 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000970 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +0000971}
972
Martin v. Löwis14694662006-02-03 12:54:16 +0000973static int
974win32_stat(const char* path, struct win32_stat *result)
975{
976 WIN32_FILE_ATTRIBUTE_DATA info;
977 int code;
978 char *dot;
979 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +0000980 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +0000981 if (GetLastError() != ERROR_SHARING_VIOLATION) {
982 /* Protocol violation: we explicitly clear errno, instead of
983 setting it to a POSIX error. Callers should use GetLastError. */
984 errno = 0;
985 return -1;
986 } else {
987 /* Could not get attributes on open file. Fall back to
988 reading the directory. */
989 if (!attributes_from_dir(path, &info)) {
990 /* Very strange. This should not fail now */
991 errno = 0;
992 return -1;
993 }
994 }
Martin v. Löwis14694662006-02-03 12:54:16 +0000995 }
996 code = attribute_data_to_stat(&info, result);
997 if (code != 0)
998 return code;
999 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1000 dot = strrchr(path, '.');
1001 if (dot) {
1002 if (stricmp(dot, ".bat") == 0 ||
1003 stricmp(dot, ".cmd") == 0 ||
1004 stricmp(dot, ".exe") == 0 ||
1005 stricmp(dot, ".com") == 0)
1006 result->st_mode |= 0111;
1007 }
1008 return code;
1009}
1010
1011static int
1012win32_wstat(const wchar_t* path, struct win32_stat *result)
1013{
1014 int code;
1015 const wchar_t *dot;
1016 WIN32_FILE_ATTRIBUTE_DATA info;
1017 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001018 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001019 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1020 /* Protocol violation: we explicitly clear errno, instead of
1021 setting it to a POSIX error. Callers should use GetLastError. */
1022 errno = 0;
1023 return -1;
1024 } else {
1025 /* Could not get attributes on open file. Fall back to
1026 reading the directory. */
1027 if (!attributes_from_dir_w(path, &info)) {
1028 /* Very strange. This should not fail now */
1029 errno = 0;
1030 return -1;
1031 }
1032 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001033 }
1034 code = attribute_data_to_stat(&info, result);
1035 if (code < 0)
1036 return code;
1037 /* Set IFEXEC if it is an .exe, .bat, ... */
1038 dot = wcsrchr(path, '.');
1039 if (dot) {
1040 if (_wcsicmp(dot, L".bat") == 0 ||
1041 _wcsicmp(dot, L".cmd") == 0 ||
1042 _wcsicmp(dot, L".exe") == 0 ||
1043 _wcsicmp(dot, L".com") == 0)
1044 result->st_mode |= 0111;
1045 }
1046 return code;
1047}
1048
1049static int
1050win32_fstat(int file_number, struct win32_stat *result)
1051{
1052 BY_HANDLE_FILE_INFORMATION info;
1053 HANDLE h;
1054 int type;
1055
1056 h = (HANDLE)_get_osfhandle(file_number);
1057
1058 /* Protocol violation: we explicitly clear errno, instead of
1059 setting it to a POSIX error. Callers should use GetLastError. */
1060 errno = 0;
1061
1062 if (h == INVALID_HANDLE_VALUE) {
1063 /* This is really a C library error (invalid file handle).
1064 We set the Win32 error to the closes one matching. */
1065 SetLastError(ERROR_INVALID_HANDLE);
1066 return -1;
1067 }
1068 memset(result, 0, sizeof(*result));
1069
1070 type = GetFileType(h);
1071 if (type == FILE_TYPE_UNKNOWN) {
1072 DWORD error = GetLastError();
1073 if (error != 0) {
1074 return -1;
1075 }
1076 /* else: valid but unknown file */
1077 }
1078
1079 if (type != FILE_TYPE_DISK) {
1080 if (type == FILE_TYPE_CHAR)
1081 result->st_mode = _S_IFCHR;
1082 else if (type == FILE_TYPE_PIPE)
1083 result->st_mode = _S_IFIFO;
1084 return 0;
1085 }
1086
1087 if (!GetFileInformationByHandle(h, &info)) {
1088 return -1;
1089 }
1090
1091 /* similar to stat() */
1092 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1093 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1094 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1095 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1096 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1097 /* specific to fstat() */
1098 result->st_nlink = info.nNumberOfLinks;
1099 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1100 return 0;
1101}
1102
1103#endif /* MS_WINDOWS */
1104
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001105PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001106"stat_result: Result from stat or lstat.\n\n\
1107This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001108 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001109or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1110\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001111Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1112or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001113\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001114See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001115
1116static PyStructSequence_Field stat_result_fields[] = {
1117 {"st_mode", "protection bits"},
1118 {"st_ino", "inode"},
1119 {"st_dev", "device"},
1120 {"st_nlink", "number of hard links"},
1121 {"st_uid", "user ID of owner"},
1122 {"st_gid", "group ID of owner"},
1123 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001124 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1125 {NULL, "integer time of last access"},
1126 {NULL, "integer time of last modification"},
1127 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001128 {"st_atime", "time of last access"},
1129 {"st_mtime", "time of last modification"},
1130 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001131#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001132 {"st_blksize", "blocksize for filesystem I/O"},
1133#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001134#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001135 {"st_blocks", "number of blocks allocated"},
1136#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001137#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001138 {"st_rdev", "device type (if inode device)"},
1139#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001140#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1141 {"st_flags", "user defined flags for file"},
1142#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001143#ifdef HAVE_STRUCT_STAT_ST_GEN
1144 {"st_gen", "generation number"},
1145#endif
1146#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1147 {"st_birthtime", "time of creation"},
1148#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001149 {0}
1150};
1151
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001152#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001153#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001154#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001155#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001156#endif
1157
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001158#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001159#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1160#else
1161#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1162#endif
1163
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001164#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001165#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1166#else
1167#define ST_RDEV_IDX ST_BLOCKS_IDX
1168#endif
1169
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001170#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1171#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1172#else
1173#define ST_FLAGS_IDX ST_RDEV_IDX
1174#endif
1175
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001176#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001177#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001178#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001179#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001180#endif
1181
1182#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1183#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1184#else
1185#define ST_BIRTHTIME_IDX ST_GEN_IDX
1186#endif
1187
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001188static PyStructSequence_Desc stat_result_desc = {
1189 "stat_result", /* name */
1190 stat_result__doc__, /* doc */
1191 stat_result_fields,
1192 10
1193};
1194
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001195PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001196"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1197This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001198 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001199or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001200\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001201See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001202
1203static PyStructSequence_Field statvfs_result_fields[] = {
1204 {"f_bsize", },
1205 {"f_frsize", },
1206 {"f_blocks", },
1207 {"f_bfree", },
1208 {"f_bavail", },
1209 {"f_files", },
1210 {"f_ffree", },
1211 {"f_favail", },
1212 {"f_flag", },
1213 {"f_namemax",},
1214 {0}
1215};
1216
1217static PyStructSequence_Desc statvfs_result_desc = {
1218 "statvfs_result", /* name */
1219 statvfs_result__doc__, /* doc */
1220 statvfs_result_fields,
1221 10
1222};
1223
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001224static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001225static PyTypeObject StatResultType;
1226static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001227static newfunc structseq_new;
1228
1229static PyObject *
1230statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1231{
1232 PyStructSequence *result;
1233 int i;
1234
1235 result = (PyStructSequence*)structseq_new(type, args, kwds);
1236 if (!result)
1237 return NULL;
1238 /* If we have been initialized from a tuple,
1239 st_?time might be set to None. Initialize it
1240 from the int slots. */
1241 for (i = 7; i <= 9; i++) {
1242 if (result->ob_item[i+3] == Py_None) {
1243 Py_DECREF(Py_None);
1244 Py_INCREF(result->ob_item[i]);
1245 result->ob_item[i+3] = result->ob_item[i];
1246 }
1247 }
1248 return (PyObject*)result;
1249}
1250
1251
1252
1253/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001254static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001255
1256PyDoc_STRVAR(stat_float_times__doc__,
1257"stat_float_times([newval]) -> oldval\n\n\
1258Determine whether os.[lf]stat represents time stamps as float objects.\n\
1259If newval is True, future calls to stat() return floats, if it is False,\n\
1260future calls return ints. \n\
1261If newval is omitted, return the current setting.\n");
1262
1263static PyObject*
1264stat_float_times(PyObject* self, PyObject *args)
1265{
1266 int newval = -1;
1267 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1268 return NULL;
1269 if (newval == -1)
1270 /* Return old value */
1271 return PyBool_FromLong(_stat_float_times);
1272 _stat_float_times = newval;
1273 Py_INCREF(Py_None);
1274 return Py_None;
1275}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001276
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001277static void
1278fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1279{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001280 PyObject *fval,*ival;
1281#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001282 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001283#else
1284 ival = PyInt_FromLong((long)sec);
1285#endif
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001286 if (!ival)
1287 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001288 if (_stat_float_times) {
1289 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1290 } else {
1291 fval = ival;
1292 Py_INCREF(fval);
1293 }
1294 PyStructSequence_SET_ITEM(v, index, ival);
1295 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001296}
1297
Tim Peters5aa91602002-01-30 05:46:57 +00001298/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001299 (used by posix_stat() and posix_fstat()) */
1300static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001301_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001302{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001303 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001304 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001305 if (v == NULL)
1306 return NULL;
1307
Martin v. Löwis14694662006-02-03 12:54:16 +00001308 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001309#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001310 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001311 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001312#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001313 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001314#endif
1315#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001316 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001317 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001318#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001319 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001320#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001321 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1322 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1323 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001324#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001325 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001326 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001327#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001328 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001329#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001330
Martin v. Löwis14694662006-02-03 12:54:16 +00001331#if defined(HAVE_STAT_TV_NSEC)
1332 ansec = st->st_atim.tv_nsec;
1333 mnsec = st->st_mtim.tv_nsec;
1334 cnsec = st->st_ctim.tv_nsec;
1335#elif defined(HAVE_STAT_TV_NSEC2)
1336 ansec = st->st_atimespec.tv_nsec;
1337 mnsec = st->st_mtimespec.tv_nsec;
1338 cnsec = st->st_ctimespec.tv_nsec;
1339#elif defined(HAVE_STAT_NSEC)
1340 ansec = st->st_atime_nsec;
1341 mnsec = st->st_mtime_nsec;
1342 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001343#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001344 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001345#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001346 fill_time(v, 7, st->st_atime, ansec);
1347 fill_time(v, 8, st->st_mtime, mnsec);
1348 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001349
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001350#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001351 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001352 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001353#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001354#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001355 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001356 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001357#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001358#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001359 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001360 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001361#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001362#ifdef HAVE_STRUCT_STAT_ST_GEN
1363 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001364 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001365#endif
1366#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1367 {
1368 PyObject *val;
1369 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001370 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001371#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001372 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001373#else
1374 bnsec = 0;
1375#endif
1376 if (_stat_float_times) {
1377 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1378 } else {
1379 val = PyInt_FromLong((long)bsec);
1380 }
1381 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1382 val);
1383 }
1384#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001385#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1386 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001387 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001388#endif
Fred Drake699f3522000-06-29 21:12:41 +00001389
1390 if (PyErr_Occurred()) {
1391 Py_DECREF(v);
1392 return NULL;
1393 }
1394
1395 return v;
1396}
1397
Martin v. Löwisd8948722004-06-02 09:57:56 +00001398#ifdef MS_WINDOWS
1399
1400/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1401 where / can be used in place of \ and the trailing slash is optional.
1402 Both SERVER and SHARE must have at least one character.
1403*/
1404
1405#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1406#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001407#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001408#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001409#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001410
Tim Peters4ad82172004-08-30 17:02:04 +00001411static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001412IsUNCRootA(char *path, int pathlen)
1413{
1414 #define ISSLASH ISSLASHA
1415
1416 int i, share;
1417
1418 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1419 /* minimum UNCRoot is \\x\y */
1420 return FALSE;
1421 for (i = 2; i < pathlen ; i++)
1422 if (ISSLASH(path[i])) break;
1423 if (i == 2 || i == pathlen)
1424 /* do not allow \\\SHARE or \\SERVER */
1425 return FALSE;
1426 share = i+1;
1427 for (i = share; i < pathlen; i++)
1428 if (ISSLASH(path[i])) break;
1429 return (i != share && (i == pathlen || i == pathlen-1));
1430
1431 #undef ISSLASH
1432}
1433
1434#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001435static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001436IsUNCRootW(Py_UNICODE *path, int pathlen)
1437{
1438 #define ISSLASH ISSLASHW
1439
1440 int i, share;
1441
1442 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1443 /* minimum UNCRoot is \\x\y */
1444 return FALSE;
1445 for (i = 2; i < pathlen ; i++)
1446 if (ISSLASH(path[i])) break;
1447 if (i == 2 || i == pathlen)
1448 /* do not allow \\\SHARE or \\SERVER */
1449 return FALSE;
1450 share = i+1;
1451 for (i = share; i < pathlen; i++)
1452 if (ISSLASH(path[i])) break;
1453 return (i != share && (i == pathlen || i == pathlen-1));
1454
1455 #undef ISSLASH
1456}
1457#endif /* Py_WIN_WIDE_FILENAMES */
1458#endif /* MS_WINDOWS */
1459
Barry Warsaw53699e91996-12-10 23:23:01 +00001460static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001461posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001462 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001463#ifdef __VMS
1464 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1465#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001466 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001467#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001468 char *wformat,
1469 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001470{
Fred Drake699f3522000-06-29 21:12:41 +00001471 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001472 char *path = NULL; /* pass this to stat; do not free() it */
1473 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001474 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001475 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001476
1477#ifdef Py_WIN_WIDE_FILENAMES
1478 /* If on wide-character-capable OS see if argument
1479 is Unicode and if so use wide API. */
1480 if (unicode_file_names()) {
1481 PyUnicodeObject *po;
1482 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001483 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1484
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001485 Py_BEGIN_ALLOW_THREADS
1486 /* PyUnicode_AS_UNICODE result OK without
1487 thread lock as it is a simple dereference. */
1488 res = wstatfunc(wpath, &st);
1489 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001490
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001491 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001492 return win32_error_unicode("stat", wpath);
1493 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001494 }
1495 /* Drop the argument parsing error as narrow strings
1496 are also valid. */
1497 PyErr_Clear();
1498 }
1499#endif
1500
Tim Peters5aa91602002-01-30 05:46:57 +00001501 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001502 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001503 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001504 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001505
Barry Warsaw53699e91996-12-10 23:23:01 +00001506 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001507 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001508 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001509
1510 if (res != 0) {
1511#ifdef MS_WINDOWS
1512 result = win32_error("stat", pathfree);
1513#else
1514 result = posix_error_with_filename(pathfree);
1515#endif
1516 }
1517 else
1518 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001519
Tim Peters500bd032001-12-19 19:05:01 +00001520 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001521 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001522}
1523
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001524/* POSIX methods */
1525
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001526PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001527"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001528Use the real uid/gid to test for access to a path. Note that most\n\
1529operations will use the effective uid/gid, therefore this routine can\n\
1530be used in a suid/sgid environment to test if the invoking user has the\n\
1531specified access to the path. The mode argument can be F_OK to test\n\
1532existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001533
1534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001535posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001536{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001537 char *path;
1538 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001539
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001540#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001541 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001542 if (unicode_file_names()) {
1543 PyUnicodeObject *po;
1544 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1545 Py_BEGIN_ALLOW_THREADS
1546 /* PyUnicode_AS_UNICODE OK without thread lock as
1547 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001548 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001549 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001550 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001551 }
1552 /* Drop the argument parsing error as narrow strings
1553 are also valid. */
1554 PyErr_Clear();
1555 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001556 if (!PyArg_ParseTuple(args, "eti:access",
1557 Py_FileSystemDefaultEncoding, &path, &mode))
1558 return 0;
1559 Py_BEGIN_ALLOW_THREADS
1560 attr = GetFileAttributesA(path);
1561 Py_END_ALLOW_THREADS
1562 PyMem_Free(path);
1563finish:
1564 if (attr == 0xFFFFFFFF)
1565 /* File does not exist, or cannot read attributes */
1566 return PyBool_FromLong(0);
1567 /* Access is possible if either write access wasn't requested, or
1568 the file isn't read-only. */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001569 return PyBool_FromLong(!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001570#else
1571 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001572 if (!PyArg_ParseTuple(args, "eti:access",
1573 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001574 return NULL;
1575 Py_BEGIN_ALLOW_THREADS
1576 res = access(path, mode);
1577 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001578 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001579 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001580#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001581}
1582
Guido van Rossumd371ff11999-01-25 16:12:23 +00001583#ifndef F_OK
1584#define F_OK 0
1585#endif
1586#ifndef R_OK
1587#define R_OK 4
1588#endif
1589#ifndef W_OK
1590#define W_OK 2
1591#endif
1592#ifndef X_OK
1593#define X_OK 1
1594#endif
1595
1596#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001597PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001598"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001599Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001600
1601static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001602posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001603{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001604 int id;
1605 char *ret;
1606
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001607 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001608 return NULL;
1609
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001610#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001611 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001612 if (id == 0) {
1613 ret = ttyname();
1614 }
1615 else {
1616 ret = NULL;
1617 }
1618#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001619 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001620#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001621 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001622 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001623 return PyUnicode_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001624}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001625#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001626
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001627#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001628PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001629"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001630Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001631
1632static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001633posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001634{
1635 char *ret;
1636 char buffer[L_ctermid];
1637
Greg Wardb48bc172000-03-01 21:51:56 +00001638#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001639 ret = ctermid_r(buffer);
1640#else
1641 ret = ctermid(buffer);
1642#endif
1643 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001644 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001645 return PyUnicode_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001646}
1647#endif
1648
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001649PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001650"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001651Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001652
Barry Warsaw53699e91996-12-10 23:23:01 +00001653static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001654posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001655{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001656#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001657 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001658#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001659 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001660#elif defined(__VMS)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001661 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001662#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001663 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001664#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001665}
1666
Fred Drake4d1e64b2002-04-15 19:40:07 +00001667#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001668PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001669"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001670Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001671opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001672
1673static PyObject *
1674posix_fchdir(PyObject *self, PyObject *fdobj)
1675{
1676 return posix_fildes(fdobj, fchdir);
1677}
1678#endif /* HAVE_FCHDIR */
1679
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001680
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001681PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001682"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001683Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001684
Barry Warsaw53699e91996-12-10 23:23:01 +00001685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001686posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001687{
Mark Hammondef8b6542001-05-13 08:04:26 +00001688 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001689 int i;
1690 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001691#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001692 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001693 if (unicode_file_names()) {
1694 PyUnicodeObject *po;
1695 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1696 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001697 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1698 if (attr != 0xFFFFFFFF) {
1699 if (i & _S_IWRITE)
1700 attr &= ~FILE_ATTRIBUTE_READONLY;
1701 else
1702 attr |= FILE_ATTRIBUTE_READONLY;
1703 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1704 }
1705 else
1706 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001707 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001708 if (!res)
1709 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001710 PyUnicode_AS_UNICODE(po));
1711 Py_INCREF(Py_None);
1712 return Py_None;
1713 }
1714 /* Drop the argument parsing error as narrow strings
1715 are also valid. */
1716 PyErr_Clear();
1717 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001718 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1719 &path, &i))
1720 return NULL;
1721 Py_BEGIN_ALLOW_THREADS
1722 attr = GetFileAttributesA(path);
1723 if (attr != 0xFFFFFFFF) {
1724 if (i & _S_IWRITE)
1725 attr &= ~FILE_ATTRIBUTE_READONLY;
1726 else
1727 attr |= FILE_ATTRIBUTE_READONLY;
1728 res = SetFileAttributesA(path, attr);
1729 }
1730 else
1731 res = 0;
1732 Py_END_ALLOW_THREADS
1733 if (!res) {
1734 win32_error("chmod", path);
1735 PyMem_Free(path);
1736 return NULL;
1737 }
1738 PyMem_Free(path);
1739 Py_INCREF(Py_None);
1740 return Py_None;
1741#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001742 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001743 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001744 return NULL;
1745 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001746 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001747 Py_END_ALLOW_THREADS
1748 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001749 return posix_error_with_allocated_filename(path);
1750 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001751 Py_INCREF(Py_None);
1752 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001753#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001754}
1755
Christian Heimes4e30a842007-11-30 22:12:06 +00001756#ifdef HAVE_FCHMOD
1757PyDoc_STRVAR(posix_fchmod__doc__,
1758"fchmod(fd, mode)\n\n\
1759Change the access permissions of the file given by file\n\
1760descriptor fd.");
1761
1762static PyObject *
1763posix_fchmod(PyObject *self, PyObject *args)
1764{
1765 int fd, mode, res;
1766 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1767 return NULL;
1768 Py_BEGIN_ALLOW_THREADS
1769 res = fchmod(fd, mode);
1770 Py_END_ALLOW_THREADS
1771 if (res < 0)
1772 return posix_error();
1773 Py_RETURN_NONE;
1774}
1775#endif /* HAVE_FCHMOD */
1776
1777#ifdef HAVE_LCHMOD
1778PyDoc_STRVAR(posix_lchmod__doc__,
1779"lchmod(path, mode)\n\n\
1780Change the access permissions of a file. If path is a symlink, this\n\
1781affects the link itself rather than the target.");
1782
1783static PyObject *
1784posix_lchmod(PyObject *self, PyObject *args)
1785{
1786 char *path = NULL;
1787 int i;
1788 int res;
1789 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1790 &path, &i))
1791 return NULL;
1792 Py_BEGIN_ALLOW_THREADS
1793 res = lchmod(path, i);
1794 Py_END_ALLOW_THREADS
1795 if (res < 0)
1796 return posix_error_with_allocated_filename(path);
1797 PyMem_Free(path);
1798 Py_RETURN_NONE;
1799}
1800#endif /* HAVE_LCHMOD */
1801
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001802
Thomas Wouterscf297e42007-02-23 15:07:44 +00001803#ifdef HAVE_CHFLAGS
1804PyDoc_STRVAR(posix_chflags__doc__,
1805"chflags(path, flags)\n\n\
1806Set file flags.");
1807
1808static PyObject *
1809posix_chflags(PyObject *self, PyObject *args)
1810{
1811 char *path;
1812 unsigned long flags;
1813 int res;
1814 if (!PyArg_ParseTuple(args, "etk:chflags",
1815 Py_FileSystemDefaultEncoding, &path, &flags))
1816 return NULL;
1817 Py_BEGIN_ALLOW_THREADS
1818 res = chflags(path, flags);
1819 Py_END_ALLOW_THREADS
1820 if (res < 0)
1821 return posix_error_with_allocated_filename(path);
1822 PyMem_Free(path);
1823 Py_INCREF(Py_None);
1824 return Py_None;
1825}
1826#endif /* HAVE_CHFLAGS */
1827
1828#ifdef HAVE_LCHFLAGS
1829PyDoc_STRVAR(posix_lchflags__doc__,
1830"lchflags(path, flags)\n\n\
1831Set file flags.\n\
1832This function will not follow symbolic links.");
1833
1834static PyObject *
1835posix_lchflags(PyObject *self, PyObject *args)
1836{
1837 char *path;
1838 unsigned long flags;
1839 int res;
1840 if (!PyArg_ParseTuple(args, "etk:lchflags",
1841 Py_FileSystemDefaultEncoding, &path, &flags))
1842 return NULL;
1843 Py_BEGIN_ALLOW_THREADS
1844 res = lchflags(path, flags);
1845 Py_END_ALLOW_THREADS
1846 if (res < 0)
1847 return posix_error_with_allocated_filename(path);
1848 PyMem_Free(path);
1849 Py_INCREF(Py_None);
1850 return Py_None;
1851}
1852#endif /* HAVE_LCHFLAGS */
1853
Martin v. Löwis244edc82001-10-04 22:44:26 +00001854#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001855PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001856"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001857Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001858
1859static PyObject *
1860posix_chroot(PyObject *self, PyObject *args)
1861{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001862 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001863}
1864#endif
1865
Guido van Rossum21142a01999-01-08 21:05:37 +00001866#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001867PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001868"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001869force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001870
1871static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001872posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001873{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001874 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001875}
1876#endif /* HAVE_FSYNC */
1877
1878#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001879
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001880#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001881extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1882#endif
1883
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001884PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001885"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001886force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001887 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001888
1889static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001890posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001891{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001892 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001893}
1894#endif /* HAVE_FDATASYNC */
1895
1896
Fredrik Lundh10723342000-07-10 16:38:09 +00001897#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001898PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001899"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001900Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001901
Barry Warsaw53699e91996-12-10 23:23:01 +00001902static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001903posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001904{
Mark Hammondef8b6542001-05-13 08:04:26 +00001905 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001906 int uid, gid;
1907 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001908 if (!PyArg_ParseTuple(args, "etii:chown",
1909 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001910 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001911 return NULL;
1912 Py_BEGIN_ALLOW_THREADS
1913 res = chown(path, (uid_t) uid, (gid_t) gid);
1914 Py_END_ALLOW_THREADS
1915 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001916 return posix_error_with_allocated_filename(path);
1917 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001918 Py_INCREF(Py_None);
1919 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001920}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001921#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001922
Christian Heimes4e30a842007-11-30 22:12:06 +00001923#ifdef HAVE_FCHOWN
1924PyDoc_STRVAR(posix_fchown__doc__,
1925"fchown(fd, uid, gid)\n\n\
1926Change the owner and group id of the file given by file descriptor\n\
1927fd to the numeric uid and gid.");
1928
1929static PyObject *
1930posix_fchown(PyObject *self, PyObject *args)
1931{
1932 int fd, uid, gid;
1933 int res;
1934 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
1935 return NULL;
1936 Py_BEGIN_ALLOW_THREADS
1937 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1938 Py_END_ALLOW_THREADS
1939 if (res < 0)
1940 return posix_error();
1941 Py_RETURN_NONE;
1942}
1943#endif /* HAVE_FCHOWN */
1944
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001945#ifdef HAVE_LCHOWN
1946PyDoc_STRVAR(posix_lchown__doc__,
1947"lchown(path, uid, gid)\n\n\
1948Change the owner and group id of path to the numeric uid and gid.\n\
1949This function will not follow symbolic links.");
1950
1951static PyObject *
1952posix_lchown(PyObject *self, PyObject *args)
1953{
1954 char *path = NULL;
1955 int uid, gid;
1956 int res;
1957 if (!PyArg_ParseTuple(args, "etii:lchown",
1958 Py_FileSystemDefaultEncoding, &path,
1959 &uid, &gid))
1960 return NULL;
1961 Py_BEGIN_ALLOW_THREADS
1962 res = lchown(path, (uid_t) uid, (gid_t) gid);
1963 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001964 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001965 return posix_error_with_allocated_filename(path);
1966 PyMem_Free(path);
1967 Py_INCREF(Py_None);
1968 return Py_None;
1969}
1970#endif /* HAVE_LCHOWN */
1971
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001972
Guido van Rossum36bc6801995-06-14 22:54:23 +00001973#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001974PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001975"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001976Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001977
Barry Warsaw53699e91996-12-10 23:23:01 +00001978static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001979posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001980{
1981 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001982 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001983
Barry Warsaw53699e91996-12-10 23:23:01 +00001984 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001985#if defined(PYOS_OS2) && defined(PYCC_GCC)
1986 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001987#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001988 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001989#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001990 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001991 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001992 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001993 return PyUnicode_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001994}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001995
1996PyDoc_STRVAR(posix_getcwdu__doc__,
1997"getcwdu() -> path\n\n\
1998Return a unicode string representing the current working directory.");
1999
2000static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002001posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002002{
2003 char buf[1026];
2004 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002005
2006#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00002007 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002008 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002009 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00002010 wchar_t *wbuf2 = wbuf;
2011 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002012 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002013 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2014 /* If the buffer is large enough, len does not include the
2015 terminating \0. If the buffer is too small, len includes
2016 the space needed for the terminator. */
2017 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2018 wbuf2 = malloc(len * sizeof(wchar_t));
2019 if (wbuf2)
2020 len = GetCurrentDirectoryW(len, wbuf2);
2021 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002022 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002023 if (!wbuf2) {
2024 PyErr_NoMemory();
2025 return NULL;
2026 }
2027 if (!len) {
2028 if (wbuf2 != wbuf) free(wbuf2);
2029 return win32_error("getcwdu", NULL);
2030 }
2031 resobj = PyUnicode_FromWideChar(wbuf2, len);
2032 if (wbuf2 != wbuf) free(wbuf2);
2033 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002034 }
2035#endif
2036
2037 Py_BEGIN_ALLOW_THREADS
2038#if defined(PYOS_OS2) && defined(PYCC_GCC)
2039 res = _getcwd2(buf, sizeof buf);
2040#else
2041 res = getcwd(buf, sizeof buf);
2042#endif
2043 Py_END_ALLOW_THREADS
2044 if (res == NULL)
2045 return posix_error();
2046 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2047}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002048#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002049
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002050
Guido van Rossumb6775db1994-08-01 11:34:53 +00002051#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002052PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002053"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002054Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002055
Barry Warsaw53699e91996-12-10 23:23:01 +00002056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002057posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002058{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002059 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002060}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002061#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002062
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002063
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002064PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002065"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002066Return a list containing the names of the entries in the directory.\n\
2067\n\
2068 path: path of directory to list\n\
2069\n\
2070The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002071entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002072
Barry Warsaw53699e91996-12-10 23:23:01 +00002073static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002074posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002075{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002076 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002077 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002078#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002079
Barry Warsaw53699e91996-12-10 23:23:01 +00002080 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002081 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002082 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002083 WIN32_FIND_DATA FileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002084 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002085 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002086 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002087
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002088#ifdef Py_WIN_WIDE_FILENAMES
2089 /* If on wide-character-capable OS see if argument
2090 is Unicode and if so use wide API. */
2091 if (unicode_file_names()) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002092 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002093 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2094 WIN32_FIND_DATAW wFileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002095 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002096 Py_UNICODE wch;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002097 /* Overallocate for \\*.*\0 */
2098 len = PyUnicode_GET_SIZE(po);
2099 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2100 if (!wnamebuf) {
2101 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002102 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002103 }
2104 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2105 wch = len > 0 ? wnamebuf[len-1] : '\0';
2106 if (wch != L'/' && wch != L'\\' && wch != L':')
2107 wnamebuf[len++] = L'\\';
2108 wcscpy(wnamebuf + len, L"*.*");
2109 if ((d = PyList_New(0)) == NULL) {
2110 free(wnamebuf);
2111 return NULL;
2112 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002113 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2114 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002115 int error = GetLastError();
2116 if (error == ERROR_FILE_NOT_FOUND) {
2117 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002118 return d;
2119 }
2120 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002121 win32_error_unicode("FindFirstFileW", wnamebuf);
2122 free(wnamebuf);
2123 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002124 }
2125 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002126 /* Skip over . and .. */
2127 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2128 wcscmp(wFileData.cFileName, L"..") != 0) {
2129 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2130 if (v == NULL) {
2131 Py_DECREF(d);
2132 d = NULL;
2133 break;
2134 }
2135 if (PyList_Append(d, v) != 0) {
2136 Py_DECREF(v);
2137 Py_DECREF(d);
2138 d = NULL;
2139 break;
2140 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002141 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002142 }
Georg Brandl622927b2006-03-07 12:48:03 +00002143 Py_BEGIN_ALLOW_THREADS
2144 result = FindNextFileW(hFindFile, &wFileData);
2145 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002146 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2147 it got to the end of the directory. */
2148 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2149 Py_DECREF(d);
2150 win32_error_unicode("FindNextFileW", wnamebuf);
2151 FindClose(hFindFile);
2152 free(wnamebuf);
2153 return NULL;
2154 }
Georg Brandl622927b2006-03-07 12:48:03 +00002155 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002156
2157 if (FindClose(hFindFile) == FALSE) {
2158 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002159 win32_error_unicode("FindClose", wnamebuf);
2160 free(wnamebuf);
2161 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002162 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002163 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002164 return d;
2165 }
2166 /* Drop the argument parsing error as narrow strings
2167 are also valid. */
2168 PyErr_Clear();
2169 }
2170#endif
2171
Tim Peters5aa91602002-01-30 05:46:57 +00002172 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002173 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002174 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002175 if (len > 0) {
2176 char ch = namebuf[len-1];
2177 if (ch != SEP && ch != ALTSEP && ch != ':')
2178 namebuf[len++] = '/';
2179 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002180 strcpy(namebuf + len, "*.*");
2181
Barry Warsaw53699e91996-12-10 23:23:01 +00002182 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002183 return NULL;
2184
2185 hFindFile = FindFirstFile(namebuf, &FileData);
2186 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002187 int error = GetLastError();
2188 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002189 return d;
2190 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002191 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002192 }
2193 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002194 /* Skip over . and .. */
2195 if (strcmp(FileData.cFileName, ".") != 0 &&
2196 strcmp(FileData.cFileName, "..") != 0) {
2197 v = PyString_FromString(FileData.cFileName);
2198 if (v == NULL) {
2199 Py_DECREF(d);
2200 d = NULL;
2201 break;
2202 }
2203 if (PyList_Append(d, v) != 0) {
2204 Py_DECREF(v);
2205 Py_DECREF(d);
2206 d = NULL;
2207 break;
2208 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002209 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002210 }
Georg Brandl622927b2006-03-07 12:48:03 +00002211 Py_BEGIN_ALLOW_THREADS
2212 result = FindNextFile(hFindFile, &FileData);
2213 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002214 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2215 it got to the end of the directory. */
2216 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2217 Py_DECREF(d);
2218 win32_error("FindNextFile", namebuf);
2219 FindClose(hFindFile);
2220 return NULL;
2221 }
Georg Brandl622927b2006-03-07 12:48:03 +00002222 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002223
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002224 if (FindClose(hFindFile) == FALSE) {
2225 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002226 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002227 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002228
2229 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002230
Tim Peters0bb44a42000-09-15 07:44:49 +00002231#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002232
2233#ifndef MAX_PATH
2234#define MAX_PATH CCHMAXPATH
2235#endif
2236 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002237 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002238 PyObject *d, *v;
2239 char namebuf[MAX_PATH+5];
2240 HDIR hdir = 1;
2241 ULONG srchcnt = 1;
2242 FILEFINDBUF3 ep;
2243 APIRET rc;
2244
Alexandre Vassalotti70a23712007-10-14 02:05:51 +00002245 if (!PyArg_ParseTuple(args, "et#:listdir",
2246 Py_FileSystemDefaultEncoding, &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002247 return NULL;
2248 if (len >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00002249 PyMem_Free(name);
2250 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002251 return NULL;
2252 }
2253 strcpy(namebuf, name);
2254 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002255 if (*pt == ALTSEP)
2256 *pt = SEP;
2257 if (namebuf[len-1] != SEP)
2258 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002259 strcpy(namebuf + len, "*.*");
2260
Neal Norwitz6c913782007-10-14 03:23:09 +00002261 if ((d = PyList_New(0)) == NULL) {
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002262 PyMem_Free(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002263 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002264 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002265
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002266 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2267 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002268 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002269 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2270 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2271 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002272
2273 if (rc != NO_ERROR) {
2274 errno = ENOENT;
Neal Norwitz6c913782007-10-14 03:23:09 +00002275 return posix_error_with_allocated_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002276 }
2277
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002278 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002279 do {
2280 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002281 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002282 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002283
2284 strcpy(namebuf, ep.achName);
2285
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002286 /* Leave Case of Name Alone -- In Native Form */
2287 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002288
2289 v = PyString_FromString(namebuf);
2290 if (v == NULL) {
2291 Py_DECREF(d);
2292 d = NULL;
2293 break;
2294 }
2295 if (PyList_Append(d, v) != 0) {
2296 Py_DECREF(v);
2297 Py_DECREF(d);
2298 d = NULL;
2299 break;
2300 }
2301 Py_DECREF(v);
2302 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2303 }
2304
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002305 PyMem_Free(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002306 return d;
2307#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002308
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002309 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002310 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002311 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002312 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002313 int arg_is_unicode = 1;
2314
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002315 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002316 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2317 arg_is_unicode = 0;
2318 PyErr_Clear();
2319 }
2320 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002321 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002322 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002323 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002324 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002325 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002326 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002327 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002328 return NULL;
2329 }
Georg Brandl622927b2006-03-07 12:48:03 +00002330 for (;;) {
2331 Py_BEGIN_ALLOW_THREADS
2332 ep = readdir(dirp);
2333 Py_END_ALLOW_THREADS
2334 if (ep == NULL)
2335 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002336 if (ep->d_name[0] == '.' &&
2337 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002338 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002339 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00002340 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002341 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002342 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002343 d = NULL;
2344 break;
2345 }
Just van Rossum96b1c902003-03-03 17:32:15 +00002346 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002347 PyObject *w;
2348
2349 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002350 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002351 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002352 if (w != NULL) {
2353 Py_DECREF(v);
2354 v = w;
2355 }
2356 else {
2357 /* fall back to the original byte string, as
2358 discussed in patch #683592 */
2359 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002360 }
Just van Rossum46c97842003-02-25 21:42:15 +00002361 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002362 if (PyList_Append(d, v) != 0) {
2363 Py_DECREF(v);
2364 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002365 d = NULL;
2366 break;
2367 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002368 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002369 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002370 if (errno != 0 && d != NULL) {
2371 /* readdir() returned NULL and set errno */
2372 closedir(dirp);
2373 Py_DECREF(d);
2374 return posix_error_with_allocated_filename(name);
2375 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002376 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002377 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002378
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002379 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002380
Tim Peters0bb44a42000-09-15 07:44:49 +00002381#endif /* which OS */
2382} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002383
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002384#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002385/* A helper function for abspath on win32 */
2386static PyObject *
2387posix__getfullpathname(PyObject *self, PyObject *args)
2388{
2389 /* assume encoded strings wont more than double no of chars */
2390 char inbuf[MAX_PATH*2];
2391 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002392 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002393 char outbuf[MAX_PATH*2];
2394 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002395#ifdef Py_WIN_WIDE_FILENAMES
2396 if (unicode_file_names()) {
2397 PyUnicodeObject *po;
2398 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2399 Py_UNICODE woutbuf[MAX_PATH*2];
2400 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002401 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002402 sizeof(woutbuf)/sizeof(woutbuf[0]),
2403 woutbuf, &wtemp))
2404 return win32_error("GetFullPathName", "");
2405 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2406 }
2407 /* Drop the argument parsing error as narrow strings
2408 are also valid. */
2409 PyErr_Clear();
2410 }
2411#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002412 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2413 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002414 &insize))
2415 return NULL;
2416 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2417 outbuf, &temp))
2418 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002419 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2420 return PyUnicode_Decode(outbuf, strlen(outbuf),
2421 Py_FileSystemDefaultEncoding, NULL);
2422 }
Mark Hammondef8b6542001-05-13 08:04:26 +00002423 return PyString_FromString(outbuf);
2424} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002425#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002426
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002427PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002428"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002429Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002430
Barry Warsaw53699e91996-12-10 23:23:01 +00002431static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002432posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002433{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002434 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002435 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002436 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002437
2438#ifdef Py_WIN_WIDE_FILENAMES
2439 if (unicode_file_names()) {
2440 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002441 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002442 Py_BEGIN_ALLOW_THREADS
2443 /* PyUnicode_AS_UNICODE OK without thread lock as
2444 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002445 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002446 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002447 if (!res)
2448 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002449 Py_INCREF(Py_None);
2450 return Py_None;
2451 }
2452 /* Drop the argument parsing error as narrow strings
2453 are also valid. */
2454 PyErr_Clear();
2455 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002456 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2457 Py_FileSystemDefaultEncoding, &path, &mode))
2458 return NULL;
2459 Py_BEGIN_ALLOW_THREADS
2460 /* PyUnicode_AS_UNICODE OK without thread lock as
2461 it is a simple dereference. */
2462 res = CreateDirectoryA(path, NULL);
2463 Py_END_ALLOW_THREADS
2464 if (!res) {
2465 win32_error("mkdir", path);
2466 PyMem_Free(path);
2467 return NULL;
2468 }
2469 PyMem_Free(path);
2470 Py_INCREF(Py_None);
2471 return Py_None;
2472#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002473
Tim Peters5aa91602002-01-30 05:46:57 +00002474 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002475 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002476 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002477 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002478#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002479 res = mkdir(path);
2480#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002481 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002482#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002483 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002484 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002485 return posix_error_with_allocated_filename(path);
2486 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002487 Py_INCREF(Py_None);
2488 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002489#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002490}
2491
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002492
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002493/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2494#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002495#include <sys/resource.h>
2496#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002497
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002498
2499#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002500PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002501"nice(inc) -> new_priority\n\n\
2502Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002503
Barry Warsaw53699e91996-12-10 23:23:01 +00002504static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002505posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002506{
2507 int increment, value;
2508
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002509 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002510 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002511
2512 /* There are two flavours of 'nice': one that returns the new
2513 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002514 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2515 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002516
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002517 If we are of the nice family that returns the new priority, we
2518 need to clear errno before the call, and check if errno is filled
2519 before calling posix_error() on a returnvalue of -1, because the
2520 -1 may be the actual new priority! */
2521
2522 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002523 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002524#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002525 if (value == 0)
2526 value = getpriority(PRIO_PROCESS, 0);
2527#endif
2528 if (value == -1 && errno != 0)
2529 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002530 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002531 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002532}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002533#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002534
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002535PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002536"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002537Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002538
Barry Warsaw53699e91996-12-10 23:23:01 +00002539static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002540posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002541{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002542#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002543 PyObject *o1, *o2;
2544 char *p1, *p2;
2545 BOOL result;
2546 if (unicode_file_names()) {
2547 if (!PyArg_ParseTuple(args, "O&O&:rename",
2548 convert_to_unicode, &o1,
2549 convert_to_unicode, &o2))
2550 PyErr_Clear();
2551 else {
2552 Py_BEGIN_ALLOW_THREADS
2553 result = MoveFileW(PyUnicode_AsUnicode(o1),
2554 PyUnicode_AsUnicode(o2));
2555 Py_END_ALLOW_THREADS
2556 Py_DECREF(o1);
2557 Py_DECREF(o2);
2558 if (!result)
2559 return win32_error("rename", NULL);
2560 Py_INCREF(Py_None);
2561 return Py_None;
2562 }
2563 }
2564 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2565 return NULL;
2566 Py_BEGIN_ALLOW_THREADS
2567 result = MoveFileA(p1, p2);
2568 Py_END_ALLOW_THREADS
2569 if (!result)
2570 return win32_error("rename", NULL);
2571 Py_INCREF(Py_None);
2572 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002573#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002574 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002575#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002576}
2577
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002578
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002579PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002580"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002581Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002582
Barry Warsaw53699e91996-12-10 23:23:01 +00002583static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002584posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002585{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002586#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002587 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002588#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002589 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002590#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002591}
2592
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002593
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002594PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002595"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002596Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002597
Barry Warsaw53699e91996-12-10 23:23:01 +00002598static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002599posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002600{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002601#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002602 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002603#else
2604 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2605#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002606}
2607
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002608
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002609#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002610PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002611"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002612Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002613
Barry Warsaw53699e91996-12-10 23:23:01 +00002614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002615posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002616{
Guido van Rossumff4949e1992-08-05 19:58:53 +00002617 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002618#ifdef MS_WINDOWS
2619 wchar_t *command;
2620 if (!PyArg_ParseTuple(args, "u:system", &command))
2621 return NULL;
2622#else
2623 char *command;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002624 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002625 return NULL;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002626#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002627 Py_BEGIN_ALLOW_THREADS
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002628#ifdef MS_WINDOWS
2629 sts = _wsystem(command);
2630#else
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002631 sts = system(command);
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002632#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002633 Py_END_ALLOW_THREADS
2634 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002635}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002636#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002637
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002638
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002639PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002640"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002641Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002642
Barry Warsaw53699e91996-12-10 23:23:01 +00002643static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002644posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002645{
2646 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002647 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002648 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002649 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002650 if (i < 0)
2651 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002652 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002653}
2654
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002655
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002656PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002657"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002658Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002659
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002660PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002661"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002662Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002663
Barry Warsaw53699e91996-12-10 23:23:01 +00002664static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002665posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002666{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002667#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002668 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002669#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002670 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002671#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002672}
2673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002674
Guido van Rossumb6775db1994-08-01 11:34:53 +00002675#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002676PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002677"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002678Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002679
Barry Warsaw53699e91996-12-10 23:23:01 +00002680static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002681posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002682{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002683 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002684 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002685
Barry Warsaw53699e91996-12-10 23:23:01 +00002686 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002687 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002688 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002689 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002690 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002691 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002692 u.sysname,
2693 u.nodename,
2694 u.release,
2695 u.version,
2696 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002697}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002698#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002699
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002700static int
2701extract_time(PyObject *t, long* sec, long* usec)
2702{
2703 long intval;
2704 if (PyFloat_Check(t)) {
2705 double tval = PyFloat_AsDouble(t);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00002706 PyObject *intobj = Py_Type(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002707 if (!intobj)
2708 return -1;
2709 intval = PyInt_AsLong(intobj);
2710 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002711 if (intval == -1 && PyErr_Occurred())
2712 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002713 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002714 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002715 if (*usec < 0)
2716 /* If rounding gave us a negative number,
2717 truncate. */
2718 *usec = 0;
2719 return 0;
2720 }
2721 intval = PyInt_AsLong(t);
2722 if (intval == -1 && PyErr_Occurred())
2723 return -1;
2724 *sec = intval;
2725 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002726 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002727}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002728
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002729PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002730"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002731utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002732Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002733second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002734
Barry Warsaw53699e91996-12-10 23:23:01 +00002735static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002736posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002737{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002738#ifdef Py_WIN_WIDE_FILENAMES
2739 PyObject *arg;
2740 PyUnicodeObject *obwpath;
2741 wchar_t *wpath = NULL;
2742 char *apath = NULL;
2743 HANDLE hFile;
2744 long atimesec, mtimesec, ausec, musec;
2745 FILETIME atime, mtime;
2746 PyObject *result = NULL;
2747
2748 if (unicode_file_names()) {
2749 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2750 wpath = PyUnicode_AS_UNICODE(obwpath);
2751 Py_BEGIN_ALLOW_THREADS
2752 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002753 NULL, OPEN_EXISTING,
2754 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002755 Py_END_ALLOW_THREADS
2756 if (hFile == INVALID_HANDLE_VALUE)
2757 return win32_error_unicode("utime", wpath);
2758 } else
2759 /* Drop the argument parsing error as narrow strings
2760 are also valid. */
2761 PyErr_Clear();
2762 }
2763 if (!wpath) {
2764 if (!PyArg_ParseTuple(args, "etO:utime",
2765 Py_FileSystemDefaultEncoding, &apath, &arg))
2766 return NULL;
2767 Py_BEGIN_ALLOW_THREADS
2768 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002769 NULL, OPEN_EXISTING,
2770 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002771 Py_END_ALLOW_THREADS
2772 if (hFile == INVALID_HANDLE_VALUE) {
2773 win32_error("utime", apath);
2774 PyMem_Free(apath);
2775 return NULL;
2776 }
2777 PyMem_Free(apath);
2778 }
2779
2780 if (arg == Py_None) {
2781 SYSTEMTIME now;
2782 GetSystemTime(&now);
2783 if (!SystemTimeToFileTime(&now, &mtime) ||
2784 !SystemTimeToFileTime(&now, &atime)) {
2785 win32_error("utime", NULL);
2786 goto done;
2787 }
2788 }
2789 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2790 PyErr_SetString(PyExc_TypeError,
2791 "utime() arg 2 must be a tuple (atime, mtime)");
2792 goto done;
2793 }
2794 else {
2795 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2796 &atimesec, &ausec) == -1)
2797 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002798 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002799 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2800 &mtimesec, &musec) == -1)
2801 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002802 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002803 }
2804 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2805 /* Avoid putting the file name into the error here,
2806 as that may confuse the user into believing that
2807 something is wrong with the file, when it also
2808 could be the time stamp that gives a problem. */
2809 win32_error("utime", NULL);
2810 }
2811 Py_INCREF(Py_None);
2812 result = Py_None;
2813done:
2814 CloseHandle(hFile);
2815 return result;
2816#else /* Py_WIN_WIDE_FILENAMES */
2817
Neal Norwitz2adf2102004-06-09 01:46:02 +00002818 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002819 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002820 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002821 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002822
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002823#if defined(HAVE_UTIMES)
2824 struct timeval buf[2];
2825#define ATIME buf[0].tv_sec
2826#define MTIME buf[1].tv_sec
2827#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002828/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002829 struct utimbuf buf;
2830#define ATIME buf.actime
2831#define MTIME buf.modtime
2832#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002833#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002834 time_t buf[2];
2835#define ATIME buf[0]
2836#define MTIME buf[1]
2837#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002838#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002839
Mark Hammond817c9292003-12-03 01:22:38 +00002840
Thomas Wouters477c8d52006-05-27 19:21:47 +00002841 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002842 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002843 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002844 if (arg == Py_None) {
2845 /* optional time values not given */
2846 Py_BEGIN_ALLOW_THREADS
2847 res = utime(path, NULL);
2848 Py_END_ALLOW_THREADS
2849 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002850 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002851 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002852 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002853 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002854 return NULL;
2855 }
2856 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002857 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002858 &atime, &ausec) == -1) {
2859 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002860 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002861 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002862 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002863 &mtime, &musec) == -1) {
2864 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002865 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002866 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002867 ATIME = atime;
2868 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002869#ifdef HAVE_UTIMES
2870 buf[0].tv_usec = ausec;
2871 buf[1].tv_usec = musec;
2872 Py_BEGIN_ALLOW_THREADS
2873 res = utimes(path, buf);
2874 Py_END_ALLOW_THREADS
2875#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002876 Py_BEGIN_ALLOW_THREADS
2877 res = utime(path, UTIME_ARG);
2878 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002879#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002880 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002881 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002882 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002883 }
Neal Norwitz96652712004-06-06 20:40:27 +00002884 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002885 Py_INCREF(Py_None);
2886 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002887#undef UTIME_ARG
2888#undef ATIME
2889#undef MTIME
Thomas Wouters477c8d52006-05-27 19:21:47 +00002890#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002891}
2892
Guido van Rossum85e3b011991-06-03 12:42:10 +00002893
Guido van Rossum3b066191991-06-04 19:40:25 +00002894/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002895
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002896PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002897"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002898Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002899
Barry Warsaw53699e91996-12-10 23:23:01 +00002900static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002901posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002902{
2903 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002904 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002905 return NULL;
2906 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002907 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002908}
2909
Martin v. Löwis114619e2002-10-07 06:44:21 +00002910#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2911static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002912free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002913{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002914 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002915 for (i = 0; i < count; i++)
2916 PyMem_Free(array[i]);
2917 PyMem_DEL(array);
2918}
2919#endif
2920
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002921
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002922#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002923PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002924"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002925Execute an executable path with arguments, replacing current process.\n\
2926\n\
2927 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002928 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002929
Barry Warsaw53699e91996-12-10 23:23:01 +00002930static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002931posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002932{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002933 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002934 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002935 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002936 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002937 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002938
Guido van Rossum89b33251993-10-22 14:26:06 +00002939 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002940 argv is a list or tuple of strings. */
2941
Martin v. Löwis114619e2002-10-07 06:44:21 +00002942 if (!PyArg_ParseTuple(args, "etO:execv",
2943 Py_FileSystemDefaultEncoding,
2944 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002945 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002946 if (PyList_Check(argv)) {
2947 argc = PyList_Size(argv);
2948 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002949 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002950 else if (PyTuple_Check(argv)) {
2951 argc = PyTuple_Size(argv);
2952 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002953 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002954 else {
Fred Drake661ea262000-10-24 19:57:45 +00002955 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002956 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002957 return NULL;
2958 }
Thomas Heller6790d602007-08-30 17:15:14 +00002959 if (argc < 1) {
2960 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
2961 PyMem_Free(path);
2962 return NULL;
2963 }
Guido van Rossum50422b42000-04-26 20:34:28 +00002964
Barry Warsaw53699e91996-12-10 23:23:01 +00002965 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002966 if (argvlist == NULL) {
2967 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002968 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002969 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002970 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002971 if (!PyArg_Parse((*getitem)(argv, i), "et",
2972 Py_FileSystemDefaultEncoding,
2973 &argvlist[i])) {
2974 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002975 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002976 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002977 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002978 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002979
Guido van Rossum85e3b011991-06-03 12:42:10 +00002980 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002981 }
2982 argvlist[argc] = NULL;
2983
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002984 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002985
Guido van Rossum85e3b011991-06-03 12:42:10 +00002986 /* If we get here it's definitely an error */
2987
Martin v. Löwis114619e2002-10-07 06:44:21 +00002988 free_string_array(argvlist, argc);
2989 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002990 return posix_error();
2991}
2992
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002993
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002994PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002995"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002996Execute a path with arguments and environment, replacing current process.\n\
2997\n\
2998 path: path of executable file\n\
2999 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003000 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003001
Barry Warsaw53699e91996-12-10 23:23:01 +00003002static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003003posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003004{
3005 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003006 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003007 char **argvlist;
3008 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003009 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003010 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003011 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003012 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003013
3014 /* execve has three arguments: (path, argv, env), where
3015 argv is a list or tuple of strings and env is a dictionary
3016 like posix.environ. */
3017
Martin v. Löwis114619e2002-10-07 06:44:21 +00003018 if (!PyArg_ParseTuple(args, "etOO:execve",
3019 Py_FileSystemDefaultEncoding,
3020 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003021 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003022 if (PyList_Check(argv)) {
3023 argc = PyList_Size(argv);
3024 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003025 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003026 else if (PyTuple_Check(argv)) {
3027 argc = PyTuple_Size(argv);
3028 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003029 }
3030 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003031 PyErr_SetString(PyExc_TypeError,
3032 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003033 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003034 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003035 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003036 PyErr_SetString(PyExc_TypeError,
3037 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003038 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003039 }
3040
Barry Warsaw53699e91996-12-10 23:23:01 +00003041 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003042 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003043 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003044 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003045 }
3046 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003047 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003048 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003049 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003050 &argvlist[i]))
3051 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003052 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003053 goto fail_1;
3054 }
3055 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003056 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003057 argvlist[argc] = NULL;
3058
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003059 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003060 if (i < 0)
3061 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003062 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003063 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003064 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003065 goto fail_1;
3066 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003067 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003068 keys = PyMapping_Keys(env);
3069 vals = PyMapping_Values(env);
3070 if (!keys || !vals)
3071 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003072 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3073 PyErr_SetString(PyExc_TypeError,
3074 "execve(): env.keys() or env.values() is not a list");
3075 goto fail_2;
3076 }
Tim Peters5aa91602002-01-30 05:46:57 +00003077
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003078 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003079 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003080 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003081
3082 key = PyList_GetItem(keys, pos);
3083 val = PyList_GetItem(vals, pos);
3084 if (!key || !val)
3085 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003086
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003087 if (!PyArg_Parse(
3088 key,
3089 "s;execve() arg 3 contains a non-string key",
3090 &k) ||
3091 !PyArg_Parse(
3092 val,
3093 "s;execve() arg 3 contains a non-string value",
3094 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003095 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003096 goto fail_2;
3097 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003098
3099#if defined(PYOS_OS2)
3100 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3101 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3102#endif
Christian Heimes830a4bc2007-11-22 07:43:40 +00003103 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003104 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003105 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003106 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003107 goto fail_2;
3108 }
Tim Petersc8996f52001-12-03 20:41:00 +00003109 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003110 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003111#if defined(PYOS_OS2)
3112 }
3113#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003114 }
3115 envlist[envc] = 0;
3116
3117 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003118
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003119 /* If we get here it's definitely an error */
3120
3121 (void) posix_error();
3122
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003123 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003124 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003125 PyMem_DEL(envlist[envc]);
3126 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003127 fail_1:
3128 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003129 Py_XDECREF(vals);
3130 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003131 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003132 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003133 return NULL;
3134}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003135#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003136
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003137
Guido van Rossuma1065681999-01-25 23:20:23 +00003138#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003139PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003140"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003141Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003142\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003143 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003144 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003145 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003146
3147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003148posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003149{
3150 char *path;
3151 PyObject *argv;
3152 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003153 int mode, i;
3154 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003155 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003156 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003157
3158 /* spawnv has three arguments: (mode, path, argv), where
3159 argv is a list or tuple of strings. */
3160
Martin v. Löwis114619e2002-10-07 06:44:21 +00003161 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3162 Py_FileSystemDefaultEncoding,
3163 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003164 return NULL;
3165 if (PyList_Check(argv)) {
3166 argc = PyList_Size(argv);
3167 getitem = PyList_GetItem;
3168 }
3169 else if (PyTuple_Check(argv)) {
3170 argc = PyTuple_Size(argv);
3171 getitem = PyTuple_GetItem;
3172 }
3173 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003174 PyErr_SetString(PyExc_TypeError,
3175 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003176 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003177 return NULL;
3178 }
3179
3180 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003181 if (argvlist == NULL) {
3182 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003183 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003184 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003185 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003186 if (!PyArg_Parse((*getitem)(argv, i), "et",
3187 Py_FileSystemDefaultEncoding,
3188 &argvlist[i])) {
3189 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003190 PyErr_SetString(
3191 PyExc_TypeError,
3192 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003193 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003194 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003195 }
3196 }
3197 argvlist[argc] = NULL;
3198
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003199#if defined(PYOS_OS2) && defined(PYCC_GCC)
3200 Py_BEGIN_ALLOW_THREADS
3201 spawnval = spawnv(mode, path, argvlist);
3202 Py_END_ALLOW_THREADS
3203#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003204 if (mode == _OLD_P_OVERLAY)
3205 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003206
Tim Peters25059d32001-12-07 20:35:43 +00003207 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003208 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003209 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003210#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003211
Martin v. Löwis114619e2002-10-07 06:44:21 +00003212 free_string_array(argvlist, argc);
3213 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003214
Fred Drake699f3522000-06-29 21:12:41 +00003215 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003216 return posix_error();
3217 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003218#if SIZEOF_LONG == SIZEOF_VOID_P
3219 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003220#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003221 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003222#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003223}
3224
3225
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003226PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003227"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003228Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003229\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003230 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003231 path: path of executable file\n\
3232 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003233 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003234
3235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003236posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003237{
3238 char *path;
3239 PyObject *argv, *env;
3240 char **argvlist;
3241 char **envlist;
3242 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003243 int mode, pos, envc;
3244 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003245 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003246 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003247 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003248
3249 /* spawnve has four arguments: (mode, path, argv, env), where
3250 argv is a list or tuple of strings and env is a dictionary
3251 like posix.environ. */
3252
Martin v. Löwis114619e2002-10-07 06:44:21 +00003253 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3254 Py_FileSystemDefaultEncoding,
3255 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003256 return NULL;
3257 if (PyList_Check(argv)) {
3258 argc = PyList_Size(argv);
3259 getitem = PyList_GetItem;
3260 }
3261 else if (PyTuple_Check(argv)) {
3262 argc = PyTuple_Size(argv);
3263 getitem = PyTuple_GetItem;
3264 }
3265 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003266 PyErr_SetString(PyExc_TypeError,
3267 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003268 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003269 }
3270 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003271 PyErr_SetString(PyExc_TypeError,
3272 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003273 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003274 }
3275
3276 argvlist = PyMem_NEW(char *, argc+1);
3277 if (argvlist == NULL) {
3278 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003279 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003280 }
3281 for (i = 0; i < argc; i++) {
3282 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003283 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003284 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003285 &argvlist[i]))
3286 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003287 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003288 goto fail_1;
3289 }
3290 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003291 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003292 argvlist[argc] = NULL;
3293
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003294 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003295 if (i < 0)
3296 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003297 envlist = PyMem_NEW(char *, i + 1);
3298 if (envlist == NULL) {
3299 PyErr_NoMemory();
3300 goto fail_1;
3301 }
3302 envc = 0;
3303 keys = PyMapping_Keys(env);
3304 vals = PyMapping_Values(env);
3305 if (!keys || !vals)
3306 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003307 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3308 PyErr_SetString(PyExc_TypeError,
3309 "spawnve(): env.keys() or env.values() is not a list");
3310 goto fail_2;
3311 }
Tim Peters5aa91602002-01-30 05:46:57 +00003312
Guido van Rossuma1065681999-01-25 23:20:23 +00003313 for (pos = 0; pos < i; pos++) {
3314 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003315 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003316
3317 key = PyList_GetItem(keys, pos);
3318 val = PyList_GetItem(vals, pos);
3319 if (!key || !val)
3320 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003321
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003322 if (!PyArg_Parse(
3323 key,
3324 "s;spawnve() arg 3 contains a non-string key",
3325 &k) ||
3326 !PyArg_Parse(
3327 val,
3328 "s;spawnve() arg 3 contains a non-string value",
3329 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003330 {
3331 goto fail_2;
3332 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003333 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003334 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003335 if (p == NULL) {
3336 PyErr_NoMemory();
3337 goto fail_2;
3338 }
Tim Petersc8996f52001-12-03 20:41:00 +00003339 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003340 envlist[envc++] = p;
3341 }
3342 envlist[envc] = 0;
3343
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003344#if defined(PYOS_OS2) && defined(PYCC_GCC)
3345 Py_BEGIN_ALLOW_THREADS
3346 spawnval = spawnve(mode, path, argvlist, envlist);
3347 Py_END_ALLOW_THREADS
3348#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003349 if (mode == _OLD_P_OVERLAY)
3350 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003351
3352 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003353 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003354 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003355#endif
Tim Peters25059d32001-12-07 20:35:43 +00003356
Fred Drake699f3522000-06-29 21:12:41 +00003357 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003358 (void) posix_error();
3359 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003360#if SIZEOF_LONG == SIZEOF_VOID_P
3361 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003362#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003363 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003364#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003365
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003366 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003367 while (--envc >= 0)
3368 PyMem_DEL(envlist[envc]);
3369 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003370 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003371 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003372 Py_XDECREF(vals);
3373 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003374 fail_0:
3375 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003376 return res;
3377}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003378
3379/* OS/2 supports spawnvp & spawnvpe natively */
3380#if defined(PYOS_OS2)
3381PyDoc_STRVAR(posix_spawnvp__doc__,
3382"spawnvp(mode, file, args)\n\n\
3383Execute the program 'file' in a new process, using the environment\n\
3384search path to find the file.\n\
3385\n\
3386 mode: mode of process creation\n\
3387 file: executable file name\n\
3388 args: tuple or list of strings");
3389
3390static PyObject *
3391posix_spawnvp(PyObject *self, PyObject *args)
3392{
3393 char *path;
3394 PyObject *argv;
3395 char **argvlist;
3396 int mode, i, argc;
3397 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003398 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003399
3400 /* spawnvp has three arguments: (mode, path, argv), where
3401 argv is a list or tuple of strings. */
3402
3403 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3404 Py_FileSystemDefaultEncoding,
3405 &path, &argv))
3406 return NULL;
3407 if (PyList_Check(argv)) {
3408 argc = PyList_Size(argv);
3409 getitem = PyList_GetItem;
3410 }
3411 else if (PyTuple_Check(argv)) {
3412 argc = PyTuple_Size(argv);
3413 getitem = PyTuple_GetItem;
3414 }
3415 else {
3416 PyErr_SetString(PyExc_TypeError,
3417 "spawnvp() arg 2 must be a tuple or list");
3418 PyMem_Free(path);
3419 return NULL;
3420 }
3421
3422 argvlist = PyMem_NEW(char *, argc+1);
3423 if (argvlist == NULL) {
3424 PyMem_Free(path);
3425 return PyErr_NoMemory();
3426 }
3427 for (i = 0; i < argc; i++) {
3428 if (!PyArg_Parse((*getitem)(argv, i), "et",
3429 Py_FileSystemDefaultEncoding,
3430 &argvlist[i])) {
3431 free_string_array(argvlist, i);
3432 PyErr_SetString(
3433 PyExc_TypeError,
3434 "spawnvp() arg 2 must contain only strings");
3435 PyMem_Free(path);
3436 return NULL;
3437 }
3438 }
3439 argvlist[argc] = NULL;
3440
3441 Py_BEGIN_ALLOW_THREADS
3442#if defined(PYCC_GCC)
3443 spawnval = spawnvp(mode, path, argvlist);
3444#else
3445 spawnval = _spawnvp(mode, path, argvlist);
3446#endif
3447 Py_END_ALLOW_THREADS
3448
3449 free_string_array(argvlist, argc);
3450 PyMem_Free(path);
3451
3452 if (spawnval == -1)
3453 return posix_error();
3454 else
3455 return Py_BuildValue("l", (long) spawnval);
3456}
3457
3458
3459PyDoc_STRVAR(posix_spawnvpe__doc__,
3460"spawnvpe(mode, file, args, env)\n\n\
3461Execute the program 'file' in a new process, using the environment\n\
3462search path to find the file.\n\
3463\n\
3464 mode: mode of process creation\n\
3465 file: executable file name\n\
3466 args: tuple or list of arguments\n\
3467 env: dictionary of strings mapping to strings");
3468
3469static PyObject *
3470posix_spawnvpe(PyObject *self, PyObject *args)
3471{
3472 char *path;
3473 PyObject *argv, *env;
3474 char **argvlist;
3475 char **envlist;
3476 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3477 int mode, i, pos, argc, envc;
3478 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003479 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003480 int lastarg = 0;
3481
3482 /* spawnvpe has four arguments: (mode, path, argv, env), where
3483 argv is a list or tuple of strings and env is a dictionary
3484 like posix.environ. */
3485
3486 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3487 Py_FileSystemDefaultEncoding,
3488 &path, &argv, &env))
3489 return NULL;
3490 if (PyList_Check(argv)) {
3491 argc = PyList_Size(argv);
3492 getitem = PyList_GetItem;
3493 }
3494 else if (PyTuple_Check(argv)) {
3495 argc = PyTuple_Size(argv);
3496 getitem = PyTuple_GetItem;
3497 }
3498 else {
3499 PyErr_SetString(PyExc_TypeError,
3500 "spawnvpe() arg 2 must be a tuple or list");
3501 goto fail_0;
3502 }
3503 if (!PyMapping_Check(env)) {
3504 PyErr_SetString(PyExc_TypeError,
3505 "spawnvpe() arg 3 must be a mapping object");
3506 goto fail_0;
3507 }
3508
3509 argvlist = PyMem_NEW(char *, argc+1);
3510 if (argvlist == NULL) {
3511 PyErr_NoMemory();
3512 goto fail_0;
3513 }
3514 for (i = 0; i < argc; i++) {
3515 if (!PyArg_Parse((*getitem)(argv, i),
3516 "et;spawnvpe() arg 2 must contain only strings",
3517 Py_FileSystemDefaultEncoding,
3518 &argvlist[i]))
3519 {
3520 lastarg = i;
3521 goto fail_1;
3522 }
3523 }
3524 lastarg = argc;
3525 argvlist[argc] = NULL;
3526
3527 i = PyMapping_Size(env);
3528 if (i < 0)
3529 goto fail_1;
3530 envlist = PyMem_NEW(char *, i + 1);
3531 if (envlist == NULL) {
3532 PyErr_NoMemory();
3533 goto fail_1;
3534 }
3535 envc = 0;
3536 keys = PyMapping_Keys(env);
3537 vals = PyMapping_Values(env);
3538 if (!keys || !vals)
3539 goto fail_2;
3540 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3541 PyErr_SetString(PyExc_TypeError,
3542 "spawnvpe(): env.keys() or env.values() is not a list");
3543 goto fail_2;
3544 }
3545
3546 for (pos = 0; pos < i; pos++) {
3547 char *p, *k, *v;
3548 size_t len;
3549
3550 key = PyList_GetItem(keys, pos);
3551 val = PyList_GetItem(vals, pos);
3552 if (!key || !val)
3553 goto fail_2;
3554
3555 if (!PyArg_Parse(
3556 key,
3557 "s;spawnvpe() arg 3 contains a non-string key",
3558 &k) ||
3559 !PyArg_Parse(
3560 val,
3561 "s;spawnvpe() arg 3 contains a non-string value",
3562 &v))
3563 {
3564 goto fail_2;
3565 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003566 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003567 p = PyMem_NEW(char, len);
3568 if (p == NULL) {
3569 PyErr_NoMemory();
3570 goto fail_2;
3571 }
3572 PyOS_snprintf(p, len, "%s=%s", k, v);
3573 envlist[envc++] = p;
3574 }
3575 envlist[envc] = 0;
3576
3577 Py_BEGIN_ALLOW_THREADS
3578#if defined(PYCC_GCC)
3579 spawnval = spawnve(mode, path, argvlist, envlist);
3580#else
3581 spawnval = _spawnve(mode, path, argvlist, envlist);
3582#endif
3583 Py_END_ALLOW_THREADS
3584
3585 if (spawnval == -1)
3586 (void) posix_error();
3587 else
3588 res = Py_BuildValue("l", (long) spawnval);
3589
3590 fail_2:
3591 while (--envc >= 0)
3592 PyMem_DEL(envlist[envc]);
3593 PyMem_DEL(envlist);
3594 fail_1:
3595 free_string_array(argvlist, lastarg);
3596 Py_XDECREF(vals);
3597 Py_XDECREF(keys);
3598 fail_0:
3599 PyMem_Free(path);
3600 return res;
3601}
3602#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003603#endif /* HAVE_SPAWNV */
3604
3605
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003606#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003607PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003608"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003609Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3610\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003611Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003612
3613static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003614posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003615{
Neal Norwitze241ce82003-02-17 18:17:05 +00003616 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003617 if (pid == -1)
3618 return posix_error();
3619 PyOS_AfterFork();
3620 return PyInt_FromLong((long)pid);
3621}
3622#endif
3623
3624
Guido van Rossumad0ee831995-03-01 10:34:45 +00003625#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003626PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003627"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003628Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003629Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003630
Barry Warsaw53699e91996-12-10 23:23:01 +00003631static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003632posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003633{
Neal Norwitze241ce82003-02-17 18:17:05 +00003634 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003635 if (pid == -1)
3636 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003637 if (pid == 0)
3638 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003639 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003640}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003641#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003642
Neal Norwitzb59798b2003-03-21 01:43:31 +00003643/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003644/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3645#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003646#define DEV_PTY_FILE "/dev/ptc"
3647#define HAVE_DEV_PTMX
3648#else
3649#define DEV_PTY_FILE "/dev/ptmx"
3650#endif
3651
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003652#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003653#ifdef HAVE_PTY_H
3654#include <pty.h>
3655#else
3656#ifdef HAVE_LIBUTIL_H
3657#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003658#endif /* HAVE_LIBUTIL_H */
3659#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003660#ifdef HAVE_STROPTS_H
3661#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003662#endif
3663#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003664
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003665#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003666PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003667"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003668Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003669
3670static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003671posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003672{
3673 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003674#ifndef HAVE_OPENPTY
3675 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003676#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003677#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003678 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003679#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003680 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003681#endif
3682#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003683
Thomas Wouters70c21a12000-07-14 14:28:33 +00003684#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003685 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3686 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003687#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003688 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3689 if (slave_name == NULL)
3690 return posix_error();
3691
3692 slave_fd = open(slave_name, O_RDWR);
3693 if (slave_fd < 0)
3694 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003695#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003696 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003697 if (master_fd < 0)
3698 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003699 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003700 /* change permission of slave */
3701 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003702 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003703 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003704 }
3705 /* unlock slave */
3706 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003707 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003708 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003709 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003710 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003711 slave_name = ptsname(master_fd); /* get name of slave */
3712 if (slave_name == NULL)
3713 return posix_error();
3714 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3715 if (slave_fd < 0)
3716 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003717#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003718 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3719 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003720#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003721 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003722#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003723#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003724#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003725
Fred Drake8cef4cf2000-06-28 16:40:38 +00003726 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003727
Fred Drake8cef4cf2000-06-28 16:40:38 +00003728}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003729#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003730
3731#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003732PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003733"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003734Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3735Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003736To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003737
3738static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003739posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003740{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003741 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003742
Fred Drake8cef4cf2000-06-28 16:40:38 +00003743 pid = forkpty(&master_fd, NULL, NULL, NULL);
3744 if (pid == -1)
3745 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003746 if (pid == 0)
3747 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003748 return Py_BuildValue("(ii)", pid, master_fd);
3749}
3750#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003751
Guido van Rossumad0ee831995-03-01 10:34:45 +00003752#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003753PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003754"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003755Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003756
Barry Warsaw53699e91996-12-10 23:23:01 +00003757static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003758posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003759{
Barry Warsaw53699e91996-12-10 23:23:01 +00003760 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003761}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003762#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003763
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003764
Guido van Rossumad0ee831995-03-01 10:34:45 +00003765#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003766PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003767"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003768Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003769
Barry Warsaw53699e91996-12-10 23:23:01 +00003770static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003771posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003772{
Barry Warsaw53699e91996-12-10 23:23:01 +00003773 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003774}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003775#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003776
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003777
Guido van Rossumad0ee831995-03-01 10:34:45 +00003778#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003779PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003780"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003781Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003782
Barry Warsaw53699e91996-12-10 23:23:01 +00003783static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003784posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003785{
Barry Warsaw53699e91996-12-10 23:23:01 +00003786 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003787}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003788#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003789
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003790
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003791PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003792"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003793Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003794
Barry Warsaw53699e91996-12-10 23:23:01 +00003795static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003796posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003797{
Barry Warsaw53699e91996-12-10 23:23:01 +00003798 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003799}
3800
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003801
Fred Drakec9680921999-12-13 16:37:25 +00003802#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003803PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003804"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003805Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003806
3807static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003808posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003809{
3810 PyObject *result = NULL;
3811
Fred Drakec9680921999-12-13 16:37:25 +00003812#ifdef NGROUPS_MAX
3813#define MAX_GROUPS NGROUPS_MAX
3814#else
3815 /* defined to be 16 on Solaris7, so this should be a small number */
3816#define MAX_GROUPS 64
3817#endif
3818 gid_t grouplist[MAX_GROUPS];
3819 int n;
3820
3821 n = getgroups(MAX_GROUPS, grouplist);
3822 if (n < 0)
3823 posix_error();
3824 else {
3825 result = PyList_New(n);
3826 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003827 int i;
3828 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003829 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003830 if (o == NULL) {
3831 Py_DECREF(result);
3832 result = NULL;
3833 break;
3834 }
3835 PyList_SET_ITEM(result, i, o);
3836 }
3837 }
3838 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003839
Fred Drakec9680921999-12-13 16:37:25 +00003840 return result;
3841}
3842#endif
3843
Martin v. Löwis606edc12002-06-13 21:09:11 +00003844#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003845PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003846"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003847Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003848
3849static PyObject *
3850posix_getpgid(PyObject *self, PyObject *args)
3851{
3852 int pid, pgid;
3853 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3854 return NULL;
3855 pgid = getpgid(pid);
3856 if (pgid < 0)
3857 return posix_error();
3858 return PyInt_FromLong((long)pgid);
3859}
3860#endif /* HAVE_GETPGID */
3861
3862
Guido van Rossumb6775db1994-08-01 11:34:53 +00003863#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003864PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003865"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003866Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003867
Barry Warsaw53699e91996-12-10 23:23:01 +00003868static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003869posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003870{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003871#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003872 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003873#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003874 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003875#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003876}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003877#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003878
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003879
Guido van Rossumb6775db1994-08-01 11:34:53 +00003880#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003881PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003882"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003883Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003884
Barry Warsaw53699e91996-12-10 23:23:01 +00003885static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003886posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003887{
Guido van Rossum64933891994-10-20 21:56:42 +00003888#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003889 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003890#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003891 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003892#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003893 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003894 Py_INCREF(Py_None);
3895 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003896}
3897
Guido van Rossumb6775db1994-08-01 11:34:53 +00003898#endif /* HAVE_SETPGRP */
3899
Guido van Rossumad0ee831995-03-01 10:34:45 +00003900#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003901PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003902"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003903Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003904
Barry Warsaw53699e91996-12-10 23:23:01 +00003905static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003906posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003907{
Barry Warsaw53699e91996-12-10 23:23:01 +00003908 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003909}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003910#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003911
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003912
Fred Drake12c6e2d1999-12-14 21:25:03 +00003913#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003914PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003915"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003916Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003917
3918static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003919posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003920{
Neal Norwitze241ce82003-02-17 18:17:05 +00003921 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003922 char *name;
3923 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003924
Fred Drakea30680b2000-12-06 21:24:28 +00003925 errno = 0;
3926 name = getlogin();
3927 if (name == NULL) {
3928 if (errno)
3929 posix_error();
3930 else
3931 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003932 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003933 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003934 else
Neal Norwitz93c56822007-08-26 07:10:06 +00003935 result = PyUnicode_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003936 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003937
Fred Drake12c6e2d1999-12-14 21:25:03 +00003938 return result;
3939}
3940#endif
3941
Guido van Rossumad0ee831995-03-01 10:34:45 +00003942#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003943PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003944"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003945Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003946
Barry Warsaw53699e91996-12-10 23:23:01 +00003947static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003948posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003949{
Barry Warsaw53699e91996-12-10 23:23:01 +00003950 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003951}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003952#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003953
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003954
Guido van Rossumad0ee831995-03-01 10:34:45 +00003955#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003956PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003957"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003958Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003959
Barry Warsaw53699e91996-12-10 23:23:01 +00003960static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003961posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003962{
3963 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003964 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003965 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003966#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003967 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3968 APIRET rc;
3969 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003970 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003971
3972 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3973 APIRET rc;
3974 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003975 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003976
3977 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003978 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003979#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003980 if (kill(pid, sig) == -1)
3981 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003982#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003983 Py_INCREF(Py_None);
3984 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003985}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003986#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003987
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003988#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003989PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003990"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003991Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003992
3993static PyObject *
3994posix_killpg(PyObject *self, PyObject *args)
3995{
3996 int pgid, sig;
3997 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3998 return NULL;
3999 if (killpg(pgid, sig) == -1)
4000 return posix_error();
4001 Py_INCREF(Py_None);
4002 return Py_None;
4003}
4004#endif
4005
Guido van Rossumc0125471996-06-28 18:55:32 +00004006#ifdef HAVE_PLOCK
4007
4008#ifdef HAVE_SYS_LOCK_H
4009#include <sys/lock.h>
4010#endif
4011
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004012PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004013"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004014Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004015
Barry Warsaw53699e91996-12-10 23:23:01 +00004016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004017posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004018{
4019 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004020 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004021 return NULL;
4022 if (plock(op) == -1)
4023 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004024 Py_INCREF(Py_None);
4025 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004026}
4027#endif
4028
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004029
Guido van Rossum3b066191991-06-04 19:40:25 +00004030
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004031
Guido van Rossumb6775db1994-08-01 11:34:53 +00004032#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004033PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004034"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004035Set the current process's user id.");
4036
Barry Warsaw53699e91996-12-10 23:23:01 +00004037static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004038posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004039{
4040 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004041 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004042 return NULL;
4043 if (setuid(uid) < 0)
4044 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004045 Py_INCREF(Py_None);
4046 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004047}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004048#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004049
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004050
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004051#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004052PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004053"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004054Set the current process's effective user id.");
4055
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004056static PyObject *
4057posix_seteuid (PyObject *self, PyObject *args)
4058{
4059 int euid;
4060 if (!PyArg_ParseTuple(args, "i", &euid)) {
4061 return NULL;
4062 } else if (seteuid(euid) < 0) {
4063 return posix_error();
4064 } else {
4065 Py_INCREF(Py_None);
4066 return Py_None;
4067 }
4068}
4069#endif /* HAVE_SETEUID */
4070
4071#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004072PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004073"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004074Set the current process's effective group id.");
4075
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004076static PyObject *
4077posix_setegid (PyObject *self, PyObject *args)
4078{
4079 int egid;
4080 if (!PyArg_ParseTuple(args, "i", &egid)) {
4081 return NULL;
4082 } else if (setegid(egid) < 0) {
4083 return posix_error();
4084 } else {
4085 Py_INCREF(Py_None);
4086 return Py_None;
4087 }
4088}
4089#endif /* HAVE_SETEGID */
4090
4091#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004092PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004093"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004094Set the current process's real and effective user ids.");
4095
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004096static PyObject *
4097posix_setreuid (PyObject *self, PyObject *args)
4098{
4099 int ruid, euid;
4100 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4101 return NULL;
4102 } else if (setreuid(ruid, euid) < 0) {
4103 return posix_error();
4104 } else {
4105 Py_INCREF(Py_None);
4106 return Py_None;
4107 }
4108}
4109#endif /* HAVE_SETREUID */
4110
4111#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004112PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004113"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004114Set the current process's real and effective group ids.");
4115
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004116static PyObject *
4117posix_setregid (PyObject *self, PyObject *args)
4118{
4119 int rgid, egid;
4120 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4121 return NULL;
4122 } else if (setregid(rgid, egid) < 0) {
4123 return posix_error();
4124 } else {
4125 Py_INCREF(Py_None);
4126 return Py_None;
4127 }
4128}
4129#endif /* HAVE_SETREGID */
4130
Guido van Rossumb6775db1994-08-01 11:34:53 +00004131#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004132PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004133"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004134Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004135
Barry Warsaw53699e91996-12-10 23:23:01 +00004136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004137posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004138{
4139 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004140 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004141 return NULL;
4142 if (setgid(gid) < 0)
4143 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004144 Py_INCREF(Py_None);
4145 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004146}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004147#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004148
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004149#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004150PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004151"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004152Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004153
4154static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004155posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004156{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004157 int i, len;
4158 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004159
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004160 if (!PySequence_Check(groups)) {
4161 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4162 return NULL;
4163 }
4164 len = PySequence_Size(groups);
4165 if (len > MAX_GROUPS) {
4166 PyErr_SetString(PyExc_ValueError, "too many groups");
4167 return NULL;
4168 }
4169 for(i = 0; i < len; i++) {
4170 PyObject *elem;
4171 elem = PySequence_GetItem(groups, i);
4172 if (!elem)
4173 return NULL;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004174 if (!PyLong_Check(elem)) {
4175 PyErr_SetString(PyExc_TypeError,
4176 "groups must be integers");
4177 Py_DECREF(elem);
4178 return NULL;
4179 } else {
4180 unsigned long x = PyLong_AsUnsignedLong(elem);
4181 if (PyErr_Occurred()) {
4182 PyErr_SetString(PyExc_TypeError,
4183 "group id too big");
Georg Brandla13c2442005-11-22 19:30:31 +00004184 Py_DECREF(elem);
4185 return NULL;
Georg Brandla13c2442005-11-22 19:30:31 +00004186 }
Georg Brandla13c2442005-11-22 19:30:31 +00004187 grouplist[i] = x;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004188 /* read back the value to see if it fitted in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00004189 if (grouplist[i] != x) {
4190 PyErr_SetString(PyExc_TypeError,
4191 "group id too big");
4192 Py_DECREF(elem);
4193 return NULL;
4194 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004195 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004196 Py_DECREF(elem);
4197 }
4198
4199 if (setgroups(len, grouplist) < 0)
4200 return posix_error();
4201 Py_INCREF(Py_None);
4202 return Py_None;
4203}
4204#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004205
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004206#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4207static PyObject *
4208wait_helper(int pid, int status, struct rusage *ru)
4209{
4210 PyObject *result;
4211 static PyObject *struct_rusage;
4212
4213 if (pid == -1)
4214 return posix_error();
4215
4216 if (struct_rusage == NULL) {
4217 PyObject *m = PyImport_ImportModule("resource");
4218 if (m == NULL)
4219 return NULL;
4220 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4221 Py_DECREF(m);
4222 if (struct_rusage == NULL)
4223 return NULL;
4224 }
4225
4226 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4227 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4228 if (!result)
4229 return NULL;
4230
4231#ifndef doubletime
4232#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4233#endif
4234
4235 PyStructSequence_SET_ITEM(result, 0,
4236 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4237 PyStructSequence_SET_ITEM(result, 1,
4238 PyFloat_FromDouble(doubletime(ru->ru_stime)));
4239#define SET_INT(result, index, value)\
4240 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
4241 SET_INT(result, 2, ru->ru_maxrss);
4242 SET_INT(result, 3, ru->ru_ixrss);
4243 SET_INT(result, 4, ru->ru_idrss);
4244 SET_INT(result, 5, ru->ru_isrss);
4245 SET_INT(result, 6, ru->ru_minflt);
4246 SET_INT(result, 7, ru->ru_majflt);
4247 SET_INT(result, 8, ru->ru_nswap);
4248 SET_INT(result, 9, ru->ru_inblock);
4249 SET_INT(result, 10, ru->ru_oublock);
4250 SET_INT(result, 11, ru->ru_msgsnd);
4251 SET_INT(result, 12, ru->ru_msgrcv);
4252 SET_INT(result, 13, ru->ru_nsignals);
4253 SET_INT(result, 14, ru->ru_nvcsw);
4254 SET_INT(result, 15, ru->ru_nivcsw);
4255#undef SET_INT
4256
4257 if (PyErr_Occurred()) {
4258 Py_DECREF(result);
4259 return NULL;
4260 }
4261
4262 return Py_BuildValue("iiN", pid, status, result);
4263}
4264#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4265
4266#ifdef HAVE_WAIT3
4267PyDoc_STRVAR(posix_wait3__doc__,
4268"wait3(options) -> (pid, status, rusage)\n\n\
4269Wait for completion of a child process.");
4270
4271static PyObject *
4272posix_wait3(PyObject *self, PyObject *args)
4273{
4274 int pid, options;
4275 struct rusage ru;
4276 WAIT_TYPE status;
4277 WAIT_STATUS_INT(status) = 0;
4278
4279 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4280 return NULL;
4281
4282 Py_BEGIN_ALLOW_THREADS
4283 pid = wait3(&status, options, &ru);
4284 Py_END_ALLOW_THREADS
4285
4286 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4287}
4288#endif /* HAVE_WAIT3 */
4289
4290#ifdef HAVE_WAIT4
4291PyDoc_STRVAR(posix_wait4__doc__,
4292"wait4(pid, options) -> (pid, status, rusage)\n\n\
4293Wait for completion of a given child process.");
4294
4295static PyObject *
4296posix_wait4(PyObject *self, PyObject *args)
4297{
4298 int pid, options;
4299 struct rusage ru;
4300 WAIT_TYPE status;
4301 WAIT_STATUS_INT(status) = 0;
4302
4303 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
4304 return NULL;
4305
4306 Py_BEGIN_ALLOW_THREADS
4307 pid = wait4(pid, &status, options, &ru);
4308 Py_END_ALLOW_THREADS
4309
4310 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4311}
4312#endif /* HAVE_WAIT4 */
4313
Guido van Rossumb6775db1994-08-01 11:34:53 +00004314#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004315PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004316"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004317Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004318
Barry Warsaw53699e91996-12-10 23:23:01 +00004319static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004320posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004321{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004322 int pid, options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004323 WAIT_TYPE status;
4324 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004325
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004326 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004327 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004328 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004329 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004330 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004331 if (pid == -1)
4332 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004333
4334 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004335}
4336
Tim Petersab034fa2002-02-01 11:27:43 +00004337#elif defined(HAVE_CWAIT)
4338
4339/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004340PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004341"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004342"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004343
4344static PyObject *
4345posix_waitpid(PyObject *self, PyObject *args)
4346{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004347 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004348 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004349
4350 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4351 return NULL;
4352 Py_BEGIN_ALLOW_THREADS
4353 pid = _cwait(&status, pid, options);
4354 Py_END_ALLOW_THREADS
4355 if (pid == -1)
4356 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004357
4358 /* shift the status left a byte so this is more like the POSIX waitpid */
4359 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004360}
4361#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004362
Guido van Rossumad0ee831995-03-01 10:34:45 +00004363#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004364PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004365"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004366Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004367
Barry Warsaw53699e91996-12-10 23:23:01 +00004368static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004369posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004370{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004371 int pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004372 WAIT_TYPE status;
4373 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004374
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004375 Py_BEGIN_ALLOW_THREADS
4376 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004377 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004378 if (pid == -1)
4379 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004380
4381 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004382}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004383#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004384
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004385
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004386PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004387"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004388Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004389
Barry Warsaw53699e91996-12-10 23:23:01 +00004390static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004391posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004392{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004393#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004394 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004395#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004396#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00004397 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004398#else
4399 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4400#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004401#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004402}
4403
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004404
Guido van Rossumb6775db1994-08-01 11:34:53 +00004405#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004406PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004407"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004408Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004409
Barry Warsaw53699e91996-12-10 23:23:01 +00004410static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004411posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004412{
Thomas Wouters89f507f2006-12-13 04:49:30 +00004413 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004414 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004415 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004416 int n;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004417 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004418
4419 if (!PyArg_ParseTuple(args, "et:readlink",
4420 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004421 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004422 v = PySequence_GetItem(args, 0);
Neal Norwitzcda5c062007-08-12 17:09:36 +00004423 if (v == NULL) {
4424 PyMem_Free(path);
4425 return NULL;
4426 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004427
4428 if (PyUnicode_Check(v)) {
4429 arg_is_unicode = 1;
4430 }
4431 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004432
Barry Warsaw53699e91996-12-10 23:23:01 +00004433 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004434 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004435 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004436 if (n < 0)
Neal Norwitzfca70052007-08-12 16:56:02 +00004437 return posix_error_with_allocated_filename(path);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004438
Neal Norwitzfca70052007-08-12 16:56:02 +00004439 PyMem_Free(path);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004440 v = PyString_FromStringAndSize(buf, n);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004441 if (arg_is_unicode) {
4442 PyObject *w;
4443
4444 w = PyUnicode_FromEncodedObject(v,
4445 Py_FileSystemDefaultEncoding,
4446 "strict");
4447 if (w != NULL) {
4448 Py_DECREF(v);
4449 v = w;
4450 }
4451 else {
4452 /* fall back to the original byte string, as
4453 discussed in patch #683592 */
4454 PyErr_Clear();
4455 }
4456 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004457 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004458}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004459#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004460
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004461
Guido van Rossumb6775db1994-08-01 11:34:53 +00004462#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004463PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004464"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004465Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004466
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004468posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004469{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004470 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004471}
4472#endif /* HAVE_SYMLINK */
4473
4474
4475#ifdef HAVE_TIMES
4476#ifndef HZ
4477#define HZ 60 /* Universal constant :-) */
4478#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004479
Guido van Rossumd48f2521997-12-05 22:19:34 +00004480#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4481static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004482system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004483{
4484 ULONG value = 0;
4485
4486 Py_BEGIN_ALLOW_THREADS
4487 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4488 Py_END_ALLOW_THREADS
4489
4490 return value;
4491}
4492
4493static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004494posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004495{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004496 /* Currently Only Uptime is Provided -- Others Later */
4497 return Py_BuildValue("ddddd",
4498 (double)0 /* t.tms_utime / HZ */,
4499 (double)0 /* t.tms_stime / HZ */,
4500 (double)0 /* t.tms_cutime / HZ */,
4501 (double)0 /* t.tms_cstime / HZ */,
4502 (double)system_uptime() / 1000);
4503}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004504#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004505static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004506posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004507{
4508 struct tms t;
4509 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004510 errno = 0;
4511 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004512 if (c == (clock_t) -1)
4513 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004514 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004515 (double)t.tms_utime / HZ,
4516 (double)t.tms_stime / HZ,
4517 (double)t.tms_cutime / HZ,
4518 (double)t.tms_cstime / HZ,
4519 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004520}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004521#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004522#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004523
4524
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004525#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004526#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004527static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004528posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004529{
4530 FILETIME create, exit, kernel, user;
4531 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004532 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004533 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4534 /* The fields of a FILETIME structure are the hi and lo part
4535 of a 64-bit value expressed in 100 nanosecond units.
4536 1e7 is one second in such units; 1e-7 the inverse.
4537 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4538 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004539 return Py_BuildValue(
4540 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004541 (double)(kernel.dwHighDateTime*429.4967296 +
4542 kernel.dwLowDateTime*1e-7),
4543 (double)(user.dwHighDateTime*429.4967296 +
4544 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004545 (double)0,
4546 (double)0,
4547 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004548}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004549#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004550
4551#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004552PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004553"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004554Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004555#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004556
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004557
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004558#ifdef HAVE_GETSID
4559PyDoc_STRVAR(posix_getsid__doc__,
4560"getsid(pid) -> sid\n\n\
4561Call the system call getsid().");
4562
4563static PyObject *
4564posix_getsid(PyObject *self, PyObject *args)
4565{
4566 int pid, sid;
4567 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
4568 return NULL;
4569 sid = getsid(pid);
4570 if (sid < 0)
4571 return posix_error();
4572 return PyInt_FromLong((long)sid);
4573}
4574#endif /* HAVE_GETSID */
4575
4576
Guido van Rossumb6775db1994-08-01 11:34:53 +00004577#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004578PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004579"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004580Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004581
Barry Warsaw53699e91996-12-10 23:23:01 +00004582static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004583posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004584{
Guido van Rossum687dd131993-05-17 08:34:16 +00004585 if (setsid() < 0)
4586 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004587 Py_INCREF(Py_None);
4588 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004589}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004590#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004591
Guido van Rossumb6775db1994-08-01 11:34:53 +00004592#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004593PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004594"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004595Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004596
Barry Warsaw53699e91996-12-10 23:23:01 +00004597static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004598posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004599{
4600 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004601 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004602 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004603 if (setpgid(pid, pgrp) < 0)
4604 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004605 Py_INCREF(Py_None);
4606 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004607}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004608#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004610
Guido van Rossumb6775db1994-08-01 11:34:53 +00004611#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004612PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004613"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004614Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004615
Barry Warsaw53699e91996-12-10 23:23:01 +00004616static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004617posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004618{
4619 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004620 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004621 return NULL;
4622 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004623 if (pgid < 0)
4624 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004625 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004626}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004627#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004628
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004629
Guido van Rossumb6775db1994-08-01 11:34:53 +00004630#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004631PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004632"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004633Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004634
Barry Warsaw53699e91996-12-10 23:23:01 +00004635static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004636posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004637{
4638 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004639 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004640 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004641 if (tcsetpgrp(fd, pgid) < 0)
4642 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004643 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004644 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004645}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004646#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004647
Guido van Rossum687dd131993-05-17 08:34:16 +00004648/* Functions acting on file descriptors */
4649
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004650PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004651"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004652Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004653
Barry Warsaw53699e91996-12-10 23:23:01 +00004654static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004655posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004656{
Mark Hammondef8b6542001-05-13 08:04:26 +00004657 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004658 int flag;
4659 int mode = 0777;
4660 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004661
4662#ifdef MS_WINDOWS
4663 if (unicode_file_names()) {
4664 PyUnicodeObject *po;
4665 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4666 Py_BEGIN_ALLOW_THREADS
4667 /* PyUnicode_AS_UNICODE OK without thread
4668 lock as it is a simple dereference. */
4669 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4670 Py_END_ALLOW_THREADS
4671 if (fd < 0)
4672 return posix_error();
4673 return PyInt_FromLong((long)fd);
4674 }
4675 /* Drop the argument parsing error as narrow strings
4676 are also valid. */
4677 PyErr_Clear();
4678 }
4679#endif
4680
Tim Peters5aa91602002-01-30 05:46:57 +00004681 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004682 Py_FileSystemDefaultEncoding, &file,
4683 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004684 return NULL;
4685
Barry Warsaw53699e91996-12-10 23:23:01 +00004686 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004687 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004688 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004689 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004690 return posix_error_with_allocated_filename(file);
4691 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004692 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004693}
4694
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004695
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004696PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004697"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004698Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004699
Barry Warsaw53699e91996-12-10 23:23:01 +00004700static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004701posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004702{
4703 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004704 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004705 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004706 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004707 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004708 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004709 if (res < 0)
4710 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004711 Py_INCREF(Py_None);
4712 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004713}
4714
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004715
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004716PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004717"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004718Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004719
Barry Warsaw53699e91996-12-10 23:23:01 +00004720static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004721posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004722{
4723 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004724 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004725 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004726 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004727 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004728 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004729 if (fd < 0)
4730 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004731 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004732}
4733
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004734
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004735PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00004736"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004737Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004738
Barry Warsaw53699e91996-12-10 23:23:01 +00004739static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004740posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004741{
4742 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004743 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004744 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004745 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004746 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004747 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004748 if (res < 0)
4749 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004750 Py_INCREF(Py_None);
4751 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004752}
4753
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004754
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004755PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004756"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004757Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004758
Barry Warsaw53699e91996-12-10 23:23:01 +00004759static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004760posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004761{
4762 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004763#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00004764 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004765#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004766 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004767#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004768 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004769 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004770 return NULL;
4771#ifdef SEEK_SET
4772 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4773 switch (how) {
4774 case 0: how = SEEK_SET; break;
4775 case 1: how = SEEK_CUR; break;
4776 case 2: how = SEEK_END; break;
4777 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004778#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004779
4780#if !defined(HAVE_LARGEFILE_SUPPORT)
4781 pos = PyInt_AsLong(posobj);
4782#else
4783 pos = PyLong_Check(posobj) ?
4784 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4785#endif
4786 if (PyErr_Occurred())
4787 return NULL;
4788
Barry Warsaw53699e91996-12-10 23:23:01 +00004789 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004790#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004791 res = _lseeki64(fd, pos, how);
4792#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004793 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004794#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004795 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004796 if (res < 0)
4797 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004798
4799#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004800 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004801#else
4802 return PyLong_FromLongLong(res);
4803#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004804}
4805
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004806
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004807PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004808"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004809Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004810
Barry Warsaw53699e91996-12-10 23:23:01 +00004811static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004812posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004813{
Guido van Rossum572dbf82007-04-27 23:53:51 +00004814 int fd, size;
4815 Py_ssize_t n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004816 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004817 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004818 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00004819 if (size < 0) {
4820 errno = EINVAL;
4821 return posix_error();
4822 }
Guido van Rossumf9e443c2007-11-21 20:17:11 +00004823 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004824 if (buffer == NULL)
4825 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004826 Py_BEGIN_ALLOW_THREADS
Guido van Rossumf9e443c2007-11-21 20:17:11 +00004827 n = read(fd, PyString_AS_STRING(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004828 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004829 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004830 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004831 return posix_error();
4832 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004833 if (n != size)
Guido van Rossumf9e443c2007-11-21 20:17:11 +00004834 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004835 return buffer;
4836}
4837
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004838
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004839PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004840"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004841Write a string to 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_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004845{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004846 int fd;
4847 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00004848 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004849
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004850 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004851 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004852 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004853 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004854 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004855 if (size < 0)
4856 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00004857 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004858}
4859
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004860
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004861PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004862"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004863Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004864
Barry Warsaw53699e91996-12-10 23:23:01 +00004865static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004866posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004867{
4868 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004869 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004870 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004871 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004872 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00004873#ifdef __VMS
4874 /* on OpenVMS we must ensure that all bytes are written to the file */
4875 fsync(fd);
4876#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004877 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004878 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004879 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00004880 if (res != 0) {
4881#ifdef MS_WINDOWS
4882 return win32_error("fstat", NULL);
4883#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004884 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00004885#endif
4886 }
Tim Peters5aa91602002-01-30 05:46:57 +00004887
Martin v. Löwis14694662006-02-03 12:54:16 +00004888 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004889}
4890
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004891PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004892"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004893Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004894connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004895
4896static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004897posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004898{
4899 int fd;
4900 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4901 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004902 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004903}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004904
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004905#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004906PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004907"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004908Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004909
Barry Warsaw53699e91996-12-10 23:23:01 +00004910static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004911posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00004912{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004913#if defined(PYOS_OS2)
4914 HFILE read, write;
4915 APIRET rc;
4916
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004917 Py_BEGIN_ALLOW_THREADS
4918 rc = DosCreatePipe( &read, &write, 4096);
4919 Py_END_ALLOW_THREADS
4920 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004921 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004922
4923 return Py_BuildValue("(ii)", read, write);
4924#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004925#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00004926 int fds[2];
4927 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00004928 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004929 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004930 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004931 if (res != 0)
4932 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004933 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004934#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00004935 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004936 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004937 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00004938 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004939 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004940 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004941 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004942 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004943 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4944 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004945 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004946#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004947#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004948}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004949#endif /* HAVE_PIPE */
4950
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004951
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004952#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004953PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00004954"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004955Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004956
Barry Warsaw53699e91996-12-10 23:23:01 +00004957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004958posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004959{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004960 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004961 int mode = 0666;
4962 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004963 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004964 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004965 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004966 res = mkfifo(filename, mode);
4967 Py_END_ALLOW_THREADS
4968 if (res < 0)
4969 return posix_error();
4970 Py_INCREF(Py_None);
4971 return Py_None;
4972}
4973#endif
4974
4975
Neal Norwitz11690112002-07-30 01:08:28 +00004976#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004977PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00004978"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004979Create a filesystem node (file, device special file or named pipe)\n\
4980named filename. mode specifies both the permissions to use and the\n\
4981type of node to be created, being combined (bitwise OR) with one of\n\
4982S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004983device defines the newly created device special file (probably using\n\
4984os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004985
4986
4987static PyObject *
4988posix_mknod(PyObject *self, PyObject *args)
4989{
4990 char *filename;
4991 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004992 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004993 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00004994 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004995 return NULL;
4996 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00004997 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00004998 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004999 if (res < 0)
5000 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005001 Py_INCREF(Py_None);
5002 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005003}
5004#endif
5005
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005006#ifdef HAVE_DEVICE_MACROS
5007PyDoc_STRVAR(posix_major__doc__,
5008"major(device) -> major number\n\
5009Extracts a device major number from a raw device number.");
5010
5011static PyObject *
5012posix_major(PyObject *self, PyObject *args)
5013{
5014 int device;
5015 if (!PyArg_ParseTuple(args, "i:major", &device))
5016 return NULL;
5017 return PyInt_FromLong((long)major(device));
5018}
5019
5020PyDoc_STRVAR(posix_minor__doc__,
5021"minor(device) -> minor number\n\
5022Extracts a device minor number from a raw device number.");
5023
5024static PyObject *
5025posix_minor(PyObject *self, PyObject *args)
5026{
5027 int device;
5028 if (!PyArg_ParseTuple(args, "i:minor", &device))
5029 return NULL;
5030 return PyInt_FromLong((long)minor(device));
5031}
5032
5033PyDoc_STRVAR(posix_makedev__doc__,
5034"makedev(major, minor) -> device number\n\
5035Composes a raw device number from the major and minor device numbers.");
5036
5037static PyObject *
5038posix_makedev(PyObject *self, PyObject *args)
5039{
5040 int major, minor;
5041 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5042 return NULL;
5043 return PyInt_FromLong((long)makedev(major, minor));
5044}
5045#endif /* device macros */
5046
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005047
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005048#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005049PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005050"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005051Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005052
Barry Warsaw53699e91996-12-10 23:23:01 +00005053static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005054posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005055{
5056 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005057 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005058 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005059 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005060
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005061 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005062 return NULL;
5063
5064#if !defined(HAVE_LARGEFILE_SUPPORT)
5065 length = PyInt_AsLong(lenobj);
5066#else
5067 length = PyLong_Check(lenobj) ?
5068 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5069#endif
5070 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005071 return NULL;
5072
Barry Warsaw53699e91996-12-10 23:23:01 +00005073 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005074 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005075 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005076 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005077 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005078 return NULL;
5079 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005080 Py_INCREF(Py_None);
5081 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005082}
5083#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005084
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005085#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005086PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005087"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005088Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005089
Fred Drake762e2061999-08-26 17:23:54 +00005090/* Save putenv() parameters as values here, so we can collect them when they
5091 * get re-set with another call for the same key. */
5092static PyObject *posix_putenv_garbage;
5093
Tim Peters5aa91602002-01-30 05:46:57 +00005094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005095posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005096{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005097#ifdef MS_WINDOWS
5098 wchar_t *s1, *s2;
5099 wchar_t *newenv;
5100#else
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005101 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005102 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005103#endif
Fred Drake762e2061999-08-26 17:23:54 +00005104 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005105 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005106
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005107 if (!PyArg_ParseTuple(args,
5108#ifdef MS_WINDOWS
5109 "uu:putenv",
5110#else
5111 "ss:putenv",
5112#endif
5113 &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005114 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005115
5116#if defined(PYOS_OS2)
5117 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5118 APIRET rc;
5119
Guido van Rossumd48f2521997-12-05 22:19:34 +00005120 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5121 if (rc != NO_ERROR)
5122 return os2_error(rc);
5123
5124 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5125 APIRET rc;
5126
Guido van Rossumd48f2521997-12-05 22:19:34 +00005127 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5128 if (rc != NO_ERROR)
5129 return os2_error(rc);
5130 } else {
5131#endif
Fred Drake762e2061999-08-26 17:23:54 +00005132 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005133 /* len includes space for a trailing \0; the size arg to
5134 PyString_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005135#ifdef MS_WINDOWS
5136 len = wcslen(s1) + wcslen(s2) + 2;
5137 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
5138#else
5139 len = strlen(s1) + strlen(s2) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00005140 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005141#endif
Fred Drake762e2061999-08-26 17:23:54 +00005142 if (newstr == NULL)
5143 return PyErr_NoMemory();
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005144#ifdef MS_WINDOWS
5145 newenv = PyUnicode_AsUnicode(newstr);
5146 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5147 if (_wputenv(newenv)) {
5148 Py_DECREF(newstr);
5149 posix_error();
5150 return NULL;
5151 }
5152#else
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005153 newenv = PyString_AS_STRING(newstr);
5154 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5155 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005156 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005157 posix_error();
5158 return NULL;
5159 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005160#endif
Fred Drake762e2061999-08-26 17:23:54 +00005161 /* Install the first arg and newstr in posix_putenv_garbage;
5162 * this will cause previous value to be collected. This has to
5163 * happen after the real putenv() call because the old value
5164 * was still accessible until then. */
5165 if (PyDict_SetItem(posix_putenv_garbage,
5166 PyTuple_GET_ITEM(args, 0), newstr)) {
5167 /* really not much we can do; just leak */
5168 PyErr_Clear();
5169 }
5170 else {
5171 Py_DECREF(newstr);
5172 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005173
5174#if defined(PYOS_OS2)
5175 }
5176#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005177 Py_INCREF(Py_None);
5178 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005179}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005180#endif /* putenv */
5181
Guido van Rossumc524d952001-10-19 01:31:59 +00005182#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005183PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005184"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005185Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005186
5187static PyObject *
5188posix_unsetenv(PyObject *self, PyObject *args)
5189{
5190 char *s1;
5191
5192 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5193 return NULL;
5194
5195 unsetenv(s1);
5196
5197 /* Remove the key from posix_putenv_garbage;
5198 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005199 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005200 * old value was still accessible until then.
5201 */
5202 if (PyDict_DelItem(posix_putenv_garbage,
5203 PyTuple_GET_ITEM(args, 0))) {
5204 /* really not much we can do; just leak */
5205 PyErr_Clear();
5206 }
5207
5208 Py_INCREF(Py_None);
5209 return Py_None;
5210}
5211#endif /* unsetenv */
5212
Guido van Rossumb6a47161997-09-15 22:54:34 +00005213#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005214PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005215"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005216Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005217
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005218static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005219posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005220{
5221 int code;
5222 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005223 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005224 return NULL;
5225 message = strerror(code);
5226 if (message == NULL) {
5227 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005228 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005229 return NULL;
5230 }
Neal Norwitz93c56822007-08-26 07:10:06 +00005231 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005232}
5233#endif /* strerror */
5234
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005235
Guido van Rossumc9641791998-08-04 15:26:23 +00005236#ifdef HAVE_SYS_WAIT_H
5237
Fred Drake106c1a02002-04-23 15:58:02 +00005238#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005239PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005240"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005241Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005242
5243static PyObject *
5244posix_WCOREDUMP(PyObject *self, PyObject *args)
5245{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005246 WAIT_TYPE status;
5247 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005248
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005249 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005250 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005251
5252 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005253}
5254#endif /* WCOREDUMP */
5255
5256#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005257PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005258"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005259Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005260job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005261
5262static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005263posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005264{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005265 WAIT_TYPE status;
5266 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005267
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005268 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005269 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005270
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005271 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005272}
5273#endif /* WIFCONTINUED */
5274
Guido van Rossumc9641791998-08-04 15:26:23 +00005275#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005276PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005277"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005278Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005279
5280static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005281posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005282{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005283 WAIT_TYPE status;
5284 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005285
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005286 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005287 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005288
Fred Drake106c1a02002-04-23 15:58:02 +00005289 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005290}
5291#endif /* WIFSTOPPED */
5292
5293#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005294PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005295"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005296Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005297
5298static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005299posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005300{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005301 WAIT_TYPE status;
5302 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005303
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005304 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005305 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005306
Fred Drake106c1a02002-04-23 15:58:02 +00005307 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005308}
5309#endif /* WIFSIGNALED */
5310
5311#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005312PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005313"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005314Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005315system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005316
5317static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005318posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005319{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005320 WAIT_TYPE status;
5321 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005322
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005323 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005324 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005325
Fred Drake106c1a02002-04-23 15:58:02 +00005326 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005327}
5328#endif /* WIFEXITED */
5329
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005330#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005331PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005332"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005333Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005334
5335static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005336posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005337{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005338 WAIT_TYPE status;
5339 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005340
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005341 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005342 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005343
Guido van Rossumc9641791998-08-04 15:26:23 +00005344 return Py_BuildValue("i", WEXITSTATUS(status));
5345}
5346#endif /* WEXITSTATUS */
5347
5348#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005349PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005350"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005351Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005352value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005353
5354static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005355posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005356{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005357 WAIT_TYPE status;
5358 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005359
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005360 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005361 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005362
Guido van Rossumc9641791998-08-04 15:26:23 +00005363 return Py_BuildValue("i", WTERMSIG(status));
5364}
5365#endif /* WTERMSIG */
5366
5367#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005368PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005369"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005370Return the signal that stopped the process that provided\n\
5371the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005372
5373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005374posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005375{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005376 WAIT_TYPE status;
5377 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005378
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005379 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005380 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005381
Guido van Rossumc9641791998-08-04 15:26:23 +00005382 return Py_BuildValue("i", WSTOPSIG(status));
5383}
5384#endif /* WSTOPSIG */
5385
5386#endif /* HAVE_SYS_WAIT_H */
5387
5388
Thomas Wouters477c8d52006-05-27 19:21:47 +00005389#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005390#ifdef _SCO_DS
5391/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5392 needed definitions in sys/statvfs.h */
5393#define _SVID3
5394#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005395#include <sys/statvfs.h>
5396
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005397static PyObject*
5398_pystatvfs_fromstructstatvfs(struct statvfs st) {
5399 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5400 if (v == NULL)
5401 return NULL;
5402
5403#if !defined(HAVE_LARGEFILE_SUPPORT)
5404 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5405 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5406 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5407 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5408 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5409 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5410 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5411 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5412 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5413 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5414#else
5415 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5416 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005417 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005418 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005419 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005420 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005421 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005422 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005423 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005424 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005425 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005426 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005427 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005428 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005429 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5430 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5431#endif
5432
5433 return v;
5434}
5435
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005436PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005437"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005438Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005439
5440static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005441posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005442{
5443 int fd, res;
5444 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005445
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005446 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005447 return NULL;
5448 Py_BEGIN_ALLOW_THREADS
5449 res = fstatvfs(fd, &st);
5450 Py_END_ALLOW_THREADS
5451 if (res != 0)
5452 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005453
5454 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005455}
Thomas Wouters477c8d52006-05-27 19:21:47 +00005456#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005457
5458
Thomas Wouters477c8d52006-05-27 19:21:47 +00005459#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005460#include <sys/statvfs.h>
5461
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005462PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005463"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005464Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005465
5466static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005467posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005468{
5469 char *path;
5470 int res;
5471 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005472 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005473 return NULL;
5474 Py_BEGIN_ALLOW_THREADS
5475 res = statvfs(path, &st);
5476 Py_END_ALLOW_THREADS
5477 if (res != 0)
5478 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005479
5480 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005481}
5482#endif /* HAVE_STATVFS */
5483
Fred Drakec9680921999-12-13 16:37:25 +00005484/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5485 * It maps strings representing configuration variable names to
5486 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005487 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005488 * rarely-used constants. There are three separate tables that use
5489 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005490 *
5491 * This code is always included, even if none of the interfaces that
5492 * need it are included. The #if hackery needed to avoid it would be
5493 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005494 */
5495struct constdef {
5496 char *name;
5497 long value;
5498};
5499
Fred Drake12c6e2d1999-12-14 21:25:03 +00005500static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005501conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005502 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005503{
5504 if (PyInt_Check(arg)) {
5505 *valuep = PyInt_AS_LONG(arg);
5506 return 1;
5507 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00005508 else {
Fred Drake12c6e2d1999-12-14 21:25:03 +00005509 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005510 size_t lo = 0;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005511 size_t mid;
Fred Drake699f3522000-06-29 21:12:41 +00005512 size_t hi = tablesize;
5513 int cmp;
Guido van Rossumbce56a62007-05-10 18:04:33 +00005514 const char *confname;
5515 Py_ssize_t namelen;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005516 if (!PyUnicode_Check(arg)) {
Guido van Rossumbce56a62007-05-10 18:04:33 +00005517 PyErr_SetString(PyExc_TypeError,
5518 "configuration names must be strings or integers");
5519 return 0;
5520 }
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005521 confname = PyUnicode_AsString(arg);
5522 if (confname == NULL)
5523 return 0;
5524 namelen = strlen(confname);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005525 while (lo < hi) {
5526 mid = (lo + hi) / 2;
5527 cmp = strcmp(confname, table[mid].name);
5528 if (cmp < 0)
5529 hi = mid;
5530 else if (cmp > 0)
5531 lo = mid + 1;
5532 else {
5533 *valuep = table[mid].value;
5534 return 1;
5535 }
5536 }
5537 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Guido van Rossumbce56a62007-05-10 18:04:33 +00005538 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005539 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005540}
5541
5542
5543#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5544static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005545#ifdef _PC_ABI_AIO_XFER_MAX
5546 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5547#endif
5548#ifdef _PC_ABI_ASYNC_IO
5549 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5550#endif
Fred Drakec9680921999-12-13 16:37:25 +00005551#ifdef _PC_ASYNC_IO
5552 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5553#endif
5554#ifdef _PC_CHOWN_RESTRICTED
5555 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5556#endif
5557#ifdef _PC_FILESIZEBITS
5558 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5559#endif
5560#ifdef _PC_LAST
5561 {"PC_LAST", _PC_LAST},
5562#endif
5563#ifdef _PC_LINK_MAX
5564 {"PC_LINK_MAX", _PC_LINK_MAX},
5565#endif
5566#ifdef _PC_MAX_CANON
5567 {"PC_MAX_CANON", _PC_MAX_CANON},
5568#endif
5569#ifdef _PC_MAX_INPUT
5570 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5571#endif
5572#ifdef _PC_NAME_MAX
5573 {"PC_NAME_MAX", _PC_NAME_MAX},
5574#endif
5575#ifdef _PC_NO_TRUNC
5576 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5577#endif
5578#ifdef _PC_PATH_MAX
5579 {"PC_PATH_MAX", _PC_PATH_MAX},
5580#endif
5581#ifdef _PC_PIPE_BUF
5582 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5583#endif
5584#ifdef _PC_PRIO_IO
5585 {"PC_PRIO_IO", _PC_PRIO_IO},
5586#endif
5587#ifdef _PC_SOCK_MAXBUF
5588 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5589#endif
5590#ifdef _PC_SYNC_IO
5591 {"PC_SYNC_IO", _PC_SYNC_IO},
5592#endif
5593#ifdef _PC_VDISABLE
5594 {"PC_VDISABLE", _PC_VDISABLE},
5595#endif
5596};
5597
Fred Drakec9680921999-12-13 16:37:25 +00005598static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005599conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005600{
5601 return conv_confname(arg, valuep, posix_constants_pathconf,
5602 sizeof(posix_constants_pathconf)
5603 / sizeof(struct constdef));
5604}
5605#endif
5606
5607#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005608PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005609"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005610Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005611If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005612
5613static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005614posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005615{
5616 PyObject *result = NULL;
5617 int name, fd;
5618
Fred Drake12c6e2d1999-12-14 21:25:03 +00005619 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5620 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005621 long limit;
5622
5623 errno = 0;
5624 limit = fpathconf(fd, name);
5625 if (limit == -1 && errno != 0)
5626 posix_error();
5627 else
5628 result = PyInt_FromLong(limit);
5629 }
5630 return result;
5631}
5632#endif
5633
5634
5635#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005636PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005637"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005638Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005639If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005640
5641static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005642posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005643{
5644 PyObject *result = NULL;
5645 int name;
5646 char *path;
5647
5648 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5649 conv_path_confname, &name)) {
5650 long limit;
5651
5652 errno = 0;
5653 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005654 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005655 if (errno == EINVAL)
5656 /* could be a path or name problem */
5657 posix_error();
5658 else
5659 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005660 }
Fred Drakec9680921999-12-13 16:37:25 +00005661 else
5662 result = PyInt_FromLong(limit);
5663 }
5664 return result;
5665}
5666#endif
5667
5668#ifdef HAVE_CONFSTR
5669static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005670#ifdef _CS_ARCHITECTURE
5671 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5672#endif
5673#ifdef _CS_HOSTNAME
5674 {"CS_HOSTNAME", _CS_HOSTNAME},
5675#endif
5676#ifdef _CS_HW_PROVIDER
5677 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5678#endif
5679#ifdef _CS_HW_SERIAL
5680 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5681#endif
5682#ifdef _CS_INITTAB_NAME
5683 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5684#endif
Fred Drakec9680921999-12-13 16:37:25 +00005685#ifdef _CS_LFS64_CFLAGS
5686 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5687#endif
5688#ifdef _CS_LFS64_LDFLAGS
5689 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5690#endif
5691#ifdef _CS_LFS64_LIBS
5692 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5693#endif
5694#ifdef _CS_LFS64_LINTFLAGS
5695 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5696#endif
5697#ifdef _CS_LFS_CFLAGS
5698 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5699#endif
5700#ifdef _CS_LFS_LDFLAGS
5701 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5702#endif
5703#ifdef _CS_LFS_LIBS
5704 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5705#endif
5706#ifdef _CS_LFS_LINTFLAGS
5707 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5708#endif
Fred Draked86ed291999-12-15 15:34:33 +00005709#ifdef _CS_MACHINE
5710 {"CS_MACHINE", _CS_MACHINE},
5711#endif
Fred Drakec9680921999-12-13 16:37:25 +00005712#ifdef _CS_PATH
5713 {"CS_PATH", _CS_PATH},
5714#endif
Fred Draked86ed291999-12-15 15:34:33 +00005715#ifdef _CS_RELEASE
5716 {"CS_RELEASE", _CS_RELEASE},
5717#endif
5718#ifdef _CS_SRPC_DOMAIN
5719 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5720#endif
5721#ifdef _CS_SYSNAME
5722 {"CS_SYSNAME", _CS_SYSNAME},
5723#endif
5724#ifdef _CS_VERSION
5725 {"CS_VERSION", _CS_VERSION},
5726#endif
Fred Drakec9680921999-12-13 16:37:25 +00005727#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5728 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5729#endif
5730#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5731 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5732#endif
5733#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5734 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5735#endif
5736#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5737 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5738#endif
5739#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5740 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5741#endif
5742#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5743 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5744#endif
5745#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5746 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5747#endif
5748#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5749 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5750#endif
5751#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5752 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5753#endif
5754#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5755 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5756#endif
5757#ifdef _CS_XBS5_LP64_OFF64_LIBS
5758 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5759#endif
5760#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5761 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5762#endif
5763#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5764 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5765#endif
5766#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5767 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5768#endif
5769#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5770 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5771#endif
5772#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5773 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5774#endif
Fred Draked86ed291999-12-15 15:34:33 +00005775#ifdef _MIPS_CS_AVAIL_PROCESSORS
5776 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5777#endif
5778#ifdef _MIPS_CS_BASE
5779 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5780#endif
5781#ifdef _MIPS_CS_HOSTID
5782 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5783#endif
5784#ifdef _MIPS_CS_HW_NAME
5785 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5786#endif
5787#ifdef _MIPS_CS_NUM_PROCESSORS
5788 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5789#endif
5790#ifdef _MIPS_CS_OSREL_MAJ
5791 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5792#endif
5793#ifdef _MIPS_CS_OSREL_MIN
5794 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5795#endif
5796#ifdef _MIPS_CS_OSREL_PATCH
5797 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5798#endif
5799#ifdef _MIPS_CS_OS_NAME
5800 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5801#endif
5802#ifdef _MIPS_CS_OS_PROVIDER
5803 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5804#endif
5805#ifdef _MIPS_CS_PROCESSORS
5806 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5807#endif
5808#ifdef _MIPS_CS_SERIAL
5809 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5810#endif
5811#ifdef _MIPS_CS_VENDOR
5812 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5813#endif
Fred Drakec9680921999-12-13 16:37:25 +00005814};
5815
5816static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005817conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005818{
5819 return conv_confname(arg, valuep, posix_constants_confstr,
5820 sizeof(posix_constants_confstr)
5821 / sizeof(struct constdef));
5822}
5823
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005824PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005825"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005826Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005827
5828static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005829posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005830{
5831 PyObject *result = NULL;
5832 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005833 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00005834
5835 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005836 int len;
Fred Drakec9680921999-12-13 16:37:25 +00005837
Fred Drakec9680921999-12-13 16:37:25 +00005838 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005839 len = confstr(name, buffer, sizeof(buffer));
5840 if (len == 0) {
5841 if (errno) {
5842 posix_error();
5843 }
5844 else {
5845 result = Py_None;
5846 Py_INCREF(Py_None);
5847 }
Fred Drakec9680921999-12-13 16:37:25 +00005848 }
5849 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005850 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00005851 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00005852 if (result != NULL)
Neal Norwitz93c56822007-08-26 07:10:06 +00005853 confstr(name, PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00005854 }
5855 else
Neal Norwitz93c56822007-08-26 07:10:06 +00005856 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00005857 }
5858 }
5859 return result;
5860}
5861#endif
5862
5863
5864#ifdef HAVE_SYSCONF
5865static struct constdef posix_constants_sysconf[] = {
5866#ifdef _SC_2_CHAR_TERM
5867 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5868#endif
5869#ifdef _SC_2_C_BIND
5870 {"SC_2_C_BIND", _SC_2_C_BIND},
5871#endif
5872#ifdef _SC_2_C_DEV
5873 {"SC_2_C_DEV", _SC_2_C_DEV},
5874#endif
5875#ifdef _SC_2_C_VERSION
5876 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5877#endif
5878#ifdef _SC_2_FORT_DEV
5879 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5880#endif
5881#ifdef _SC_2_FORT_RUN
5882 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5883#endif
5884#ifdef _SC_2_LOCALEDEF
5885 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5886#endif
5887#ifdef _SC_2_SW_DEV
5888 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5889#endif
5890#ifdef _SC_2_UPE
5891 {"SC_2_UPE", _SC_2_UPE},
5892#endif
5893#ifdef _SC_2_VERSION
5894 {"SC_2_VERSION", _SC_2_VERSION},
5895#endif
Fred Draked86ed291999-12-15 15:34:33 +00005896#ifdef _SC_ABI_ASYNCHRONOUS_IO
5897 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5898#endif
5899#ifdef _SC_ACL
5900 {"SC_ACL", _SC_ACL},
5901#endif
Fred Drakec9680921999-12-13 16:37:25 +00005902#ifdef _SC_AIO_LISTIO_MAX
5903 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5904#endif
Fred Drakec9680921999-12-13 16:37:25 +00005905#ifdef _SC_AIO_MAX
5906 {"SC_AIO_MAX", _SC_AIO_MAX},
5907#endif
5908#ifdef _SC_AIO_PRIO_DELTA_MAX
5909 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5910#endif
5911#ifdef _SC_ARG_MAX
5912 {"SC_ARG_MAX", _SC_ARG_MAX},
5913#endif
5914#ifdef _SC_ASYNCHRONOUS_IO
5915 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5916#endif
5917#ifdef _SC_ATEXIT_MAX
5918 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5919#endif
Fred Draked86ed291999-12-15 15:34:33 +00005920#ifdef _SC_AUDIT
5921 {"SC_AUDIT", _SC_AUDIT},
5922#endif
Fred Drakec9680921999-12-13 16:37:25 +00005923#ifdef _SC_AVPHYS_PAGES
5924 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5925#endif
5926#ifdef _SC_BC_BASE_MAX
5927 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5928#endif
5929#ifdef _SC_BC_DIM_MAX
5930 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5931#endif
5932#ifdef _SC_BC_SCALE_MAX
5933 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5934#endif
5935#ifdef _SC_BC_STRING_MAX
5936 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5937#endif
Fred Draked86ed291999-12-15 15:34:33 +00005938#ifdef _SC_CAP
5939 {"SC_CAP", _SC_CAP},
5940#endif
Fred Drakec9680921999-12-13 16:37:25 +00005941#ifdef _SC_CHARCLASS_NAME_MAX
5942 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5943#endif
5944#ifdef _SC_CHAR_BIT
5945 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5946#endif
5947#ifdef _SC_CHAR_MAX
5948 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5949#endif
5950#ifdef _SC_CHAR_MIN
5951 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5952#endif
5953#ifdef _SC_CHILD_MAX
5954 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5955#endif
5956#ifdef _SC_CLK_TCK
5957 {"SC_CLK_TCK", _SC_CLK_TCK},
5958#endif
5959#ifdef _SC_COHER_BLKSZ
5960 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5961#endif
5962#ifdef _SC_COLL_WEIGHTS_MAX
5963 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5964#endif
5965#ifdef _SC_DCACHE_ASSOC
5966 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5967#endif
5968#ifdef _SC_DCACHE_BLKSZ
5969 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5970#endif
5971#ifdef _SC_DCACHE_LINESZ
5972 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5973#endif
5974#ifdef _SC_DCACHE_SZ
5975 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5976#endif
5977#ifdef _SC_DCACHE_TBLKSZ
5978 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5979#endif
5980#ifdef _SC_DELAYTIMER_MAX
5981 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5982#endif
5983#ifdef _SC_EQUIV_CLASS_MAX
5984 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5985#endif
5986#ifdef _SC_EXPR_NEST_MAX
5987 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5988#endif
5989#ifdef _SC_FSYNC
5990 {"SC_FSYNC", _SC_FSYNC},
5991#endif
5992#ifdef _SC_GETGR_R_SIZE_MAX
5993 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5994#endif
5995#ifdef _SC_GETPW_R_SIZE_MAX
5996 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5997#endif
5998#ifdef _SC_ICACHE_ASSOC
5999 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6000#endif
6001#ifdef _SC_ICACHE_BLKSZ
6002 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6003#endif
6004#ifdef _SC_ICACHE_LINESZ
6005 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6006#endif
6007#ifdef _SC_ICACHE_SZ
6008 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6009#endif
Fred Draked86ed291999-12-15 15:34:33 +00006010#ifdef _SC_INF
6011 {"SC_INF", _SC_INF},
6012#endif
Fred Drakec9680921999-12-13 16:37:25 +00006013#ifdef _SC_INT_MAX
6014 {"SC_INT_MAX", _SC_INT_MAX},
6015#endif
6016#ifdef _SC_INT_MIN
6017 {"SC_INT_MIN", _SC_INT_MIN},
6018#endif
6019#ifdef _SC_IOV_MAX
6020 {"SC_IOV_MAX", _SC_IOV_MAX},
6021#endif
Fred Draked86ed291999-12-15 15:34:33 +00006022#ifdef _SC_IP_SECOPTS
6023 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6024#endif
Fred Drakec9680921999-12-13 16:37:25 +00006025#ifdef _SC_JOB_CONTROL
6026 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6027#endif
Fred Draked86ed291999-12-15 15:34:33 +00006028#ifdef _SC_KERN_POINTERS
6029 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6030#endif
6031#ifdef _SC_KERN_SIM
6032 {"SC_KERN_SIM", _SC_KERN_SIM},
6033#endif
Fred Drakec9680921999-12-13 16:37:25 +00006034#ifdef _SC_LINE_MAX
6035 {"SC_LINE_MAX", _SC_LINE_MAX},
6036#endif
6037#ifdef _SC_LOGIN_NAME_MAX
6038 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6039#endif
6040#ifdef _SC_LOGNAME_MAX
6041 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6042#endif
6043#ifdef _SC_LONG_BIT
6044 {"SC_LONG_BIT", _SC_LONG_BIT},
6045#endif
Fred Draked86ed291999-12-15 15:34:33 +00006046#ifdef _SC_MAC
6047 {"SC_MAC", _SC_MAC},
6048#endif
Fred Drakec9680921999-12-13 16:37:25 +00006049#ifdef _SC_MAPPED_FILES
6050 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6051#endif
6052#ifdef _SC_MAXPID
6053 {"SC_MAXPID", _SC_MAXPID},
6054#endif
6055#ifdef _SC_MB_LEN_MAX
6056 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6057#endif
6058#ifdef _SC_MEMLOCK
6059 {"SC_MEMLOCK", _SC_MEMLOCK},
6060#endif
6061#ifdef _SC_MEMLOCK_RANGE
6062 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6063#endif
6064#ifdef _SC_MEMORY_PROTECTION
6065 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6066#endif
6067#ifdef _SC_MESSAGE_PASSING
6068 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6069#endif
Fred Draked86ed291999-12-15 15:34:33 +00006070#ifdef _SC_MMAP_FIXED_ALIGNMENT
6071 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6072#endif
Fred Drakec9680921999-12-13 16:37:25 +00006073#ifdef _SC_MQ_OPEN_MAX
6074 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6075#endif
6076#ifdef _SC_MQ_PRIO_MAX
6077 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6078#endif
Fred Draked86ed291999-12-15 15:34:33 +00006079#ifdef _SC_NACLS_MAX
6080 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6081#endif
Fred Drakec9680921999-12-13 16:37:25 +00006082#ifdef _SC_NGROUPS_MAX
6083 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6084#endif
6085#ifdef _SC_NL_ARGMAX
6086 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6087#endif
6088#ifdef _SC_NL_LANGMAX
6089 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6090#endif
6091#ifdef _SC_NL_MSGMAX
6092 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6093#endif
6094#ifdef _SC_NL_NMAX
6095 {"SC_NL_NMAX", _SC_NL_NMAX},
6096#endif
6097#ifdef _SC_NL_SETMAX
6098 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6099#endif
6100#ifdef _SC_NL_TEXTMAX
6101 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6102#endif
6103#ifdef _SC_NPROCESSORS_CONF
6104 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6105#endif
6106#ifdef _SC_NPROCESSORS_ONLN
6107 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6108#endif
Fred Draked86ed291999-12-15 15:34:33 +00006109#ifdef _SC_NPROC_CONF
6110 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6111#endif
6112#ifdef _SC_NPROC_ONLN
6113 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6114#endif
Fred Drakec9680921999-12-13 16:37:25 +00006115#ifdef _SC_NZERO
6116 {"SC_NZERO", _SC_NZERO},
6117#endif
6118#ifdef _SC_OPEN_MAX
6119 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6120#endif
6121#ifdef _SC_PAGESIZE
6122 {"SC_PAGESIZE", _SC_PAGESIZE},
6123#endif
6124#ifdef _SC_PAGE_SIZE
6125 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6126#endif
6127#ifdef _SC_PASS_MAX
6128 {"SC_PASS_MAX", _SC_PASS_MAX},
6129#endif
6130#ifdef _SC_PHYS_PAGES
6131 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6132#endif
6133#ifdef _SC_PII
6134 {"SC_PII", _SC_PII},
6135#endif
6136#ifdef _SC_PII_INTERNET
6137 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6138#endif
6139#ifdef _SC_PII_INTERNET_DGRAM
6140 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6141#endif
6142#ifdef _SC_PII_INTERNET_STREAM
6143 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6144#endif
6145#ifdef _SC_PII_OSI
6146 {"SC_PII_OSI", _SC_PII_OSI},
6147#endif
6148#ifdef _SC_PII_OSI_CLTS
6149 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6150#endif
6151#ifdef _SC_PII_OSI_COTS
6152 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6153#endif
6154#ifdef _SC_PII_OSI_M
6155 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6156#endif
6157#ifdef _SC_PII_SOCKET
6158 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6159#endif
6160#ifdef _SC_PII_XTI
6161 {"SC_PII_XTI", _SC_PII_XTI},
6162#endif
6163#ifdef _SC_POLL
6164 {"SC_POLL", _SC_POLL},
6165#endif
6166#ifdef _SC_PRIORITIZED_IO
6167 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6168#endif
6169#ifdef _SC_PRIORITY_SCHEDULING
6170 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6171#endif
6172#ifdef _SC_REALTIME_SIGNALS
6173 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6174#endif
6175#ifdef _SC_RE_DUP_MAX
6176 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6177#endif
6178#ifdef _SC_RTSIG_MAX
6179 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6180#endif
6181#ifdef _SC_SAVED_IDS
6182 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6183#endif
6184#ifdef _SC_SCHAR_MAX
6185 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6186#endif
6187#ifdef _SC_SCHAR_MIN
6188 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6189#endif
6190#ifdef _SC_SELECT
6191 {"SC_SELECT", _SC_SELECT},
6192#endif
6193#ifdef _SC_SEMAPHORES
6194 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6195#endif
6196#ifdef _SC_SEM_NSEMS_MAX
6197 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6198#endif
6199#ifdef _SC_SEM_VALUE_MAX
6200 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6201#endif
6202#ifdef _SC_SHARED_MEMORY_OBJECTS
6203 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6204#endif
6205#ifdef _SC_SHRT_MAX
6206 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6207#endif
6208#ifdef _SC_SHRT_MIN
6209 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6210#endif
6211#ifdef _SC_SIGQUEUE_MAX
6212 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6213#endif
6214#ifdef _SC_SIGRT_MAX
6215 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6216#endif
6217#ifdef _SC_SIGRT_MIN
6218 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6219#endif
Fred Draked86ed291999-12-15 15:34:33 +00006220#ifdef _SC_SOFTPOWER
6221 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6222#endif
Fred Drakec9680921999-12-13 16:37:25 +00006223#ifdef _SC_SPLIT_CACHE
6224 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6225#endif
6226#ifdef _SC_SSIZE_MAX
6227 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6228#endif
6229#ifdef _SC_STACK_PROT
6230 {"SC_STACK_PROT", _SC_STACK_PROT},
6231#endif
6232#ifdef _SC_STREAM_MAX
6233 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6234#endif
6235#ifdef _SC_SYNCHRONIZED_IO
6236 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6237#endif
6238#ifdef _SC_THREADS
6239 {"SC_THREADS", _SC_THREADS},
6240#endif
6241#ifdef _SC_THREAD_ATTR_STACKADDR
6242 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6243#endif
6244#ifdef _SC_THREAD_ATTR_STACKSIZE
6245 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6246#endif
6247#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6248 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6249#endif
6250#ifdef _SC_THREAD_KEYS_MAX
6251 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6252#endif
6253#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6254 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6255#endif
6256#ifdef _SC_THREAD_PRIO_INHERIT
6257 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6258#endif
6259#ifdef _SC_THREAD_PRIO_PROTECT
6260 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6261#endif
6262#ifdef _SC_THREAD_PROCESS_SHARED
6263 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6264#endif
6265#ifdef _SC_THREAD_SAFE_FUNCTIONS
6266 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6267#endif
6268#ifdef _SC_THREAD_STACK_MIN
6269 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6270#endif
6271#ifdef _SC_THREAD_THREADS_MAX
6272 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6273#endif
6274#ifdef _SC_TIMERS
6275 {"SC_TIMERS", _SC_TIMERS},
6276#endif
6277#ifdef _SC_TIMER_MAX
6278 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6279#endif
6280#ifdef _SC_TTY_NAME_MAX
6281 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6282#endif
6283#ifdef _SC_TZNAME_MAX
6284 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6285#endif
6286#ifdef _SC_T_IOV_MAX
6287 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6288#endif
6289#ifdef _SC_UCHAR_MAX
6290 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6291#endif
6292#ifdef _SC_UINT_MAX
6293 {"SC_UINT_MAX", _SC_UINT_MAX},
6294#endif
6295#ifdef _SC_UIO_MAXIOV
6296 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6297#endif
6298#ifdef _SC_ULONG_MAX
6299 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6300#endif
6301#ifdef _SC_USHRT_MAX
6302 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6303#endif
6304#ifdef _SC_VERSION
6305 {"SC_VERSION", _SC_VERSION},
6306#endif
6307#ifdef _SC_WORD_BIT
6308 {"SC_WORD_BIT", _SC_WORD_BIT},
6309#endif
6310#ifdef _SC_XBS5_ILP32_OFF32
6311 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6312#endif
6313#ifdef _SC_XBS5_ILP32_OFFBIG
6314 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6315#endif
6316#ifdef _SC_XBS5_LP64_OFF64
6317 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6318#endif
6319#ifdef _SC_XBS5_LPBIG_OFFBIG
6320 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6321#endif
6322#ifdef _SC_XOPEN_CRYPT
6323 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6324#endif
6325#ifdef _SC_XOPEN_ENH_I18N
6326 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6327#endif
6328#ifdef _SC_XOPEN_LEGACY
6329 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6330#endif
6331#ifdef _SC_XOPEN_REALTIME
6332 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6333#endif
6334#ifdef _SC_XOPEN_REALTIME_THREADS
6335 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6336#endif
6337#ifdef _SC_XOPEN_SHM
6338 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6339#endif
6340#ifdef _SC_XOPEN_UNIX
6341 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6342#endif
6343#ifdef _SC_XOPEN_VERSION
6344 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6345#endif
6346#ifdef _SC_XOPEN_XCU_VERSION
6347 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6348#endif
6349#ifdef _SC_XOPEN_XPG2
6350 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6351#endif
6352#ifdef _SC_XOPEN_XPG3
6353 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6354#endif
6355#ifdef _SC_XOPEN_XPG4
6356 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6357#endif
6358};
6359
6360static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006361conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006362{
6363 return conv_confname(arg, valuep, posix_constants_sysconf,
6364 sizeof(posix_constants_sysconf)
6365 / sizeof(struct constdef));
6366}
6367
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006368PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006369"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006370Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006371
6372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006373posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006374{
6375 PyObject *result = NULL;
6376 int name;
6377
6378 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6379 int value;
6380
6381 errno = 0;
6382 value = sysconf(name);
6383 if (value == -1 && errno != 0)
6384 posix_error();
6385 else
6386 result = PyInt_FromLong(value);
6387 }
6388 return result;
6389}
6390#endif
6391
6392
Fred Drakebec628d1999-12-15 18:31:10 +00006393/* This code is used to ensure that the tables of configuration value names
6394 * are in sorted order as required by conv_confname(), and also to build the
6395 * the exported dictionaries that are used to publish information about the
6396 * names available on the host platform.
6397 *
6398 * Sorting the table at runtime ensures that the table is properly ordered
6399 * when used, even for platforms we're not able to test on. It also makes
6400 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006401 */
Fred Drakebec628d1999-12-15 18:31:10 +00006402
6403static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006404cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006405{
6406 const struct constdef *c1 =
6407 (const struct constdef *) v1;
6408 const struct constdef *c2 =
6409 (const struct constdef *) v2;
6410
6411 return strcmp(c1->name, c2->name);
6412}
6413
6414static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006415setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006416 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006417{
Fred Drakebec628d1999-12-15 18:31:10 +00006418 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006419 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006420
6421 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6422 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006423 if (d == NULL)
6424 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006425
Barry Warsaw3155db32000-04-13 15:20:40 +00006426 for (i=0; i < tablesize; ++i) {
6427 PyObject *o = PyInt_FromLong(table[i].value);
6428 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6429 Py_XDECREF(o);
6430 Py_DECREF(d);
6431 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006432 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006433 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006434 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006435 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006436}
6437
Fred Drakebec628d1999-12-15 18:31:10 +00006438/* Return -1 on failure, 0 on success. */
6439static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006440setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006441{
6442#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006443 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006444 sizeof(posix_constants_pathconf)
6445 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006446 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006447 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006448#endif
6449#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006450 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006451 sizeof(posix_constants_confstr)
6452 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006453 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006454 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006455#endif
6456#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006457 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006458 sizeof(posix_constants_sysconf)
6459 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006460 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006461 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006462#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006463 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006464}
Fred Draked86ed291999-12-15 15:34:33 +00006465
6466
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006467PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006468"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006469Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006470in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006471
6472static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006473posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006474{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006475 abort();
6476 /*NOTREACHED*/
6477 Py_FatalError("abort() called from Python code didn't abort!");
6478 return NULL;
6479}
Fred Drakebec628d1999-12-15 18:31:10 +00006480
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006481#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006482PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00006483"startfile(filepath [, operation]) - Start a file with its associated\n\
6484application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006485\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00006486When \"operation\" is not specified or \"open\", this acts like\n\
6487double-clicking the file in Explorer, or giving the file name as an\n\
6488argument to the DOS \"start\" command: the file is opened with whatever\n\
6489application (if any) its extension is associated.\n\
6490When another \"operation\" is given, it specifies what should be done with\n\
6491the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006492\n\
6493startfile returns as soon as the associated application is launched.\n\
6494There is no option to wait for the application to close, and no way\n\
6495to retrieve the application's exit status.\n\
6496\n\
6497The filepath is relative to the current directory. If you want to use\n\
6498an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006499the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006500
6501static PyObject *
6502win32_startfile(PyObject *self, PyObject *args)
6503{
6504 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00006505 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006506 HINSTANCE rc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006507#ifdef Py_WIN_WIDE_FILENAMES
6508 if (unicode_file_names()) {
6509 PyObject *unipath, *woperation = NULL;
6510 if (!PyArg_ParseTuple(args, "U|s:startfile",
6511 &unipath, &operation)) {
6512 PyErr_Clear();
6513 goto normal;
6514 }
6515
6516
6517 if (operation) {
6518 woperation = PyUnicode_DecodeASCII(operation,
6519 strlen(operation), NULL);
6520 if (!woperation) {
6521 PyErr_Clear();
6522 operation = NULL;
6523 goto normal;
6524 }
6525 }
6526
6527 Py_BEGIN_ALLOW_THREADS
6528 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6529 PyUnicode_AS_UNICODE(unipath),
6530 NULL, NULL, SW_SHOWNORMAL);
6531 Py_END_ALLOW_THREADS
6532
6533 Py_XDECREF(woperation);
6534 if (rc <= (HINSTANCE)32) {
6535 PyObject *errval = win32_error_unicode("startfile",
6536 PyUnicode_AS_UNICODE(unipath));
6537 return errval;
6538 }
6539 Py_INCREF(Py_None);
6540 return Py_None;
6541 }
6542#endif
6543
6544normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00006545 if (!PyArg_ParseTuple(args, "et|s:startfile",
6546 Py_FileSystemDefaultEncoding, &filepath,
6547 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00006548 return NULL;
6549 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00006550 rc = ShellExecute((HWND)0, operation, filepath,
6551 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006552 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00006553 if (rc <= (HINSTANCE)32) {
6554 PyObject *errval = win32_error("startfile", filepath);
6555 PyMem_Free(filepath);
6556 return errval;
6557 }
6558 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006559 Py_INCREF(Py_None);
6560 return Py_None;
6561}
6562#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006563
Martin v. Löwis438b5342002-12-27 10:16:42 +00006564#ifdef HAVE_GETLOADAVG
6565PyDoc_STRVAR(posix_getloadavg__doc__,
6566"getloadavg() -> (float, float, float)\n\n\
6567Return the number of processes in the system run queue averaged over\n\
6568the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6569was unobtainable");
6570
6571static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006572posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006573{
6574 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006575 if (getloadavg(loadavg, 3)!=3) {
6576 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6577 return NULL;
6578 } else
6579 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6580}
6581#endif
6582
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006583#ifdef MS_WINDOWS
6584
6585PyDoc_STRVAR(win32_urandom__doc__,
6586"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006587Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006588
6589typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6590 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6591 DWORD dwFlags );
6592typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6593 BYTE *pbBuffer );
6594
6595static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00006596/* This handle is never explicitly released. Instead, the operating
6597 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006598static HCRYPTPROV hCryptProv = 0;
6599
Tim Peters4ad82172004-08-30 17:02:04 +00006600static PyObject*
6601win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006602{
Tim Petersd3115382004-08-30 17:36:46 +00006603 int howMany;
6604 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006605
Tim Peters4ad82172004-08-30 17:02:04 +00006606 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00006607 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00006608 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00006609 if (howMany < 0)
6610 return PyErr_Format(PyExc_ValueError,
6611 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006612
Tim Peters4ad82172004-08-30 17:02:04 +00006613 if (hCryptProv == 0) {
6614 HINSTANCE hAdvAPI32 = NULL;
6615 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006616
Tim Peters4ad82172004-08-30 17:02:04 +00006617 /* Obtain handle to the DLL containing CryptoAPI
6618 This should not fail */
6619 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6620 if(hAdvAPI32 == NULL)
6621 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006622
Tim Peters4ad82172004-08-30 17:02:04 +00006623 /* Obtain pointers to the CryptoAPI functions
6624 This will fail on some early versions of Win95 */
6625 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6626 hAdvAPI32,
6627 "CryptAcquireContextA");
6628 if (pCryptAcquireContext == NULL)
6629 return PyErr_Format(PyExc_NotImplementedError,
6630 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006631
Tim Peters4ad82172004-08-30 17:02:04 +00006632 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6633 hAdvAPI32, "CryptGenRandom");
Thomas Wouters89f507f2006-12-13 04:49:30 +00006634 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00006635 return PyErr_Format(PyExc_NotImplementedError,
6636 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006637
Tim Peters4ad82172004-08-30 17:02:04 +00006638 /* Acquire context */
6639 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
6640 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
6641 return win32_error("CryptAcquireContext", NULL);
6642 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006643
Tim Peters4ad82172004-08-30 17:02:04 +00006644 /* Allocate bytes */
Guido van Rossum18980842007-11-21 21:53:11 +00006645 result = PyString_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00006646 if (result != NULL) {
6647 /* Get random data */
6648 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Guido van Rossum18980842007-11-21 21:53:11 +00006649 PyString_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00006650 Py_DECREF(result);
6651 return win32_error("CryptGenRandom", NULL);
6652 }
Tim Peters4ad82172004-08-30 17:02:04 +00006653 }
Tim Petersd3115382004-08-30 17:36:46 +00006654 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006655}
6656#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00006657
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006658PyDoc_STRVAR(device_encoding__doc__,
6659"device_encoding(fd) -> str\n\n\
6660Return a string describing the encoding of the device\n\
6661if the output is a terminal; else return None.");
6662
6663static PyObject *
6664device_encoding(PyObject *self, PyObject *args)
6665{
6666 int fd;
6667 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
6668 return NULL;
6669 if (!isatty(fd)) {
6670 Py_INCREF(Py_None);
6671 return Py_None;
6672 }
6673#if defined(MS_WINDOWS) || defined(MS_WIN64)
6674 if (fd == 0) {
6675 char buf[100];
6676 sprintf(buf, "cp%d", GetConsoleCP());
6677 return PyUnicode_FromString(buf);
6678 }
6679 if (fd == 1 || fd == 2) {
6680 char buf[100];
6681 sprintf(buf, "cp%d", GetConsoleOutputCP());
6682 return PyUnicode_FromString(buf);
6683 }
6684#elif defined(CODESET)
6685 {
6686 char *codeset = nl_langinfo(CODESET);
6687 if (codeset)
6688 return PyUnicode_FromString(codeset);
6689 }
6690#endif
6691 Py_INCREF(Py_None);
6692 return Py_None;
6693}
6694
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006695#ifdef __VMS
6696/* Use openssl random routine */
6697#include <openssl/rand.h>
6698PyDoc_STRVAR(vms_urandom__doc__,
6699"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006700Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006701
6702static PyObject*
6703vms_urandom(PyObject *self, PyObject *args)
6704{
6705 int howMany;
6706 PyObject* result;
6707
6708 /* Read arguments */
6709 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
6710 return NULL;
6711 if (howMany < 0)
6712 return PyErr_Format(PyExc_ValueError,
6713 "negative argument not allowed");
6714
6715 /* Allocate bytes */
Guido van Rossum18980842007-11-21 21:53:11 +00006716 result = PyString_FromStringAndSize(NULL, howMany);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006717 if (result != NULL) {
6718 /* Get random data */
6719 if (RAND_pseudo_bytes((unsigned char*)
Guido van Rossum18980842007-11-21 21:53:11 +00006720 PyString_AS_STRING(result),
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006721 howMany) < 0) {
6722 Py_DECREF(result);
6723 return PyErr_Format(PyExc_ValueError,
6724 "RAND_pseudo_bytes");
6725 }
6726 }
6727 return result;
6728}
6729#endif
6730
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006731static PyMethodDef posix_methods[] = {
6732 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6733#ifdef HAVE_TTYNAME
6734 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6735#endif
6736 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00006737#ifdef HAVE_CHFLAGS
6738 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
6739#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006740 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00006741#ifdef HAVE_FCHMOD
6742 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
6743#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006744#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006745 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006746#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00006747#ifdef HAVE_LCHMOD
6748 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
6749#endif /* HAVE_LCHMOD */
6750#ifdef HAVE_FCHOWN
6751 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
6752#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00006753#ifdef HAVE_LCHFLAGS
6754 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
6755#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006756#ifdef HAVE_LCHOWN
6757 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6758#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006759#ifdef HAVE_CHROOT
6760 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6761#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006762#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006763 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006764#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006765#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00006766 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Neal Norwitze241ce82003-02-17 18:17:05 +00006767 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006768#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006769#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006770 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006771#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006772 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6773 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6774 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006775#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006776 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006777#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006778#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006779 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006780#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006781 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6782 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6783 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006784 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006785#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006786 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006787#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006788#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006789 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006790#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006791 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006792#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00006793 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006794#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006795 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6796 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6797 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006798#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00006799 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006800#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006801 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006802#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006803 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6804 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006805#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006806#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006807 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6808 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006809#if defined(PYOS_OS2)
6810 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
6811 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
6812#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00006813#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006814#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00006815 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006816#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006817#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00006818 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006819#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006820#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00006821 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006822#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006823#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00006824 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00006825#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006826#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006827 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006828#endif /* HAVE_GETEGID */
6829#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006830 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006831#endif /* HAVE_GETEUID */
6832#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006833 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006834#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006835#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00006836 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00006837#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00006838 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006839#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006840 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006841#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006842#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00006843 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006844#endif /* HAVE_GETPPID */
6845#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006846 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006847#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006848#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00006849 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00006850#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006851#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006852 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006853#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006854#ifdef HAVE_KILLPG
6855 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6856#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006857#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006858 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006859#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00006860#ifdef MS_WINDOWS
6861 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
6862#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006863#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006864 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006865#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006866#ifdef HAVE_SETEUID
6867 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6868#endif /* HAVE_SETEUID */
6869#ifdef HAVE_SETEGID
6870 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6871#endif /* HAVE_SETEGID */
6872#ifdef HAVE_SETREUID
6873 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6874#endif /* HAVE_SETREUID */
6875#ifdef HAVE_SETREGID
6876 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6877#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006878#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006879 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006880#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006881#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00006882 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006883#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006884#ifdef HAVE_GETPGID
6885 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6886#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006887#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006888 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006889#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006890#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00006891 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006892#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006893#ifdef HAVE_WAIT3
6894 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
6895#endif /* HAVE_WAIT3 */
6896#ifdef HAVE_WAIT4
6897 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
6898#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00006899#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006900 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006901#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006902#ifdef HAVE_GETSID
6903 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
6904#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006905#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00006906 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006907#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006908#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006909 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006910#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006911#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006912 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006913#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006914#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006915 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006916#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006917 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6918 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006919 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006920 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6921 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6922 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6923 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6924 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6925 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006926 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006927#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00006928 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006929#endif
6930#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006931 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006932#endif
Neal Norwitz11690112002-07-30 01:08:28 +00006933#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006934 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6935#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006936#ifdef HAVE_DEVICE_MACROS
6937 {"major", posix_major, METH_VARARGS, posix_major__doc__},
6938 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
6939 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
6940#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006941#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006942 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006943#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006944#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006945 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006946#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006947#ifdef HAVE_UNSETENV
6948 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6949#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006950#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006951 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006952#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006953#ifdef HAVE_FCHDIR
6954 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6955#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006956#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006957 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006958#endif
6959#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006960 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006961#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006962#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006963#ifdef WCOREDUMP
6964 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6965#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006966#ifdef WIFCONTINUED
6967 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6968#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006969#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006970 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006971#endif /* WIFSTOPPED */
6972#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006973 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006974#endif /* WIFSIGNALED */
6975#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006976 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006977#endif /* WIFEXITED */
6978#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006979 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006980#endif /* WEXITSTATUS */
6981#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006982 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006983#endif /* WTERMSIG */
6984#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006985 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006986#endif /* WSTOPSIG */
6987#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00006988#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006989 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006990#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00006991#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006992 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006993#endif
Fred Drakec9680921999-12-13 16:37:25 +00006994#ifdef HAVE_CONFSTR
6995 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6996#endif
6997#ifdef HAVE_SYSCONF
6998 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6999#endif
7000#ifdef HAVE_FPATHCONF
7001 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7002#endif
7003#ifdef HAVE_PATHCONF
7004 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7005#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007006 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007007#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007008 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7009#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007010#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007011 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007012#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007013 #ifdef MS_WINDOWS
7014 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7015 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007016 #ifdef __VMS
7017 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
7018 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007019 {NULL, NULL} /* Sentinel */
7020};
7021
7022
Barry Warsaw4a342091996-12-19 23:50:02 +00007023static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007024ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007025{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007026 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007027}
7028
Guido van Rossumd48f2521997-12-05 22:19:34 +00007029#if defined(PYOS_OS2)
7030/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007031static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007032{
7033 APIRET rc;
7034 ULONG values[QSV_MAX+1];
7035 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007036 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007037
7038 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007039 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007040 Py_END_ALLOW_THREADS
7041
7042 if (rc != NO_ERROR) {
7043 os2_error(rc);
7044 return -1;
7045 }
7046
Fred Drake4d1e64b2002-04-15 19:40:07 +00007047 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7048 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7049 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7050 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7051 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7052 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7053 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007054
7055 switch (values[QSV_VERSION_MINOR]) {
7056 case 0: ver = "2.00"; break;
7057 case 10: ver = "2.10"; break;
7058 case 11: ver = "2.11"; break;
7059 case 30: ver = "3.00"; break;
7060 case 40: ver = "4.00"; break;
7061 case 50: ver = "5.00"; break;
7062 default:
Tim Peters885d4572001-11-28 20:27:42 +00007063 PyOS_snprintf(tmp, sizeof(tmp),
7064 "%d-%d", values[QSV_VERSION_MAJOR],
7065 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007066 ver = &tmp[0];
7067 }
7068
7069 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007070 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007071 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007072
7073 /* Add Indicator of Which Drive was Used to Boot the System */
7074 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7075 tmp[1] = ':';
7076 tmp[2] = '\0';
7077
Fred Drake4d1e64b2002-04-15 19:40:07 +00007078 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007079}
7080#endif
7081
Barry Warsaw4a342091996-12-19 23:50:02 +00007082static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007083all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007084{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007085#ifdef F_OK
7086 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007087#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007088#ifdef R_OK
7089 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007090#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007091#ifdef W_OK
7092 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007093#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007094#ifdef X_OK
7095 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007096#endif
Fred Drakec9680921999-12-13 16:37:25 +00007097#ifdef NGROUPS_MAX
7098 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7099#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007100#ifdef TMP_MAX
7101 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7102#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007103#ifdef WCONTINUED
7104 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7105#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007106#ifdef WNOHANG
7107 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007108#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007109#ifdef WUNTRACED
7110 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7111#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007112#ifdef O_RDONLY
7113 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7114#endif
7115#ifdef O_WRONLY
7116 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7117#endif
7118#ifdef O_RDWR
7119 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7120#endif
7121#ifdef O_NDELAY
7122 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7123#endif
7124#ifdef O_NONBLOCK
7125 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7126#endif
7127#ifdef O_APPEND
7128 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7129#endif
7130#ifdef O_DSYNC
7131 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7132#endif
7133#ifdef O_RSYNC
7134 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7135#endif
7136#ifdef O_SYNC
7137 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7138#endif
7139#ifdef O_NOCTTY
7140 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7141#endif
7142#ifdef O_CREAT
7143 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7144#endif
7145#ifdef O_EXCL
7146 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7147#endif
7148#ifdef O_TRUNC
7149 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7150#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007151#ifdef O_BINARY
7152 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7153#endif
7154#ifdef O_TEXT
7155 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7156#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007157#ifdef O_LARGEFILE
7158 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7159#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007160#ifdef O_SHLOCK
7161 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7162#endif
7163#ifdef O_EXLOCK
7164 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7165#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007166
Tim Peters5aa91602002-01-30 05:46:57 +00007167/* MS Windows */
7168#ifdef O_NOINHERIT
7169 /* Don't inherit in child processes. */
7170 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7171#endif
7172#ifdef _O_SHORT_LIVED
7173 /* Optimize for short life (keep in memory). */
7174 /* MS forgot to define this one with a non-underscore form too. */
7175 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7176#endif
7177#ifdef O_TEMPORARY
7178 /* Automatically delete when last handle is closed. */
7179 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7180#endif
7181#ifdef O_RANDOM
7182 /* Optimize for random access. */
7183 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7184#endif
7185#ifdef O_SEQUENTIAL
7186 /* Optimize for sequential access. */
7187 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7188#endif
7189
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007190/* GNU extensions. */
7191#ifdef O_DIRECT
7192 /* Direct disk access. */
7193 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7194#endif
7195#ifdef O_DIRECTORY
7196 /* Must be a directory. */
7197 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7198#endif
7199#ifdef O_NOFOLLOW
7200 /* Do not follow links. */
7201 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7202#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00007203#ifdef O_NOATIME
7204 /* Do not update the access time. */
7205 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
7206#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007207
Barry Warsaw5676bd12003-01-07 20:57:09 +00007208 /* These come from sysexits.h */
7209#ifdef EX_OK
7210 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007211#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007212#ifdef EX_USAGE
7213 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007214#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007215#ifdef EX_DATAERR
7216 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007217#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007218#ifdef EX_NOINPUT
7219 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007220#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007221#ifdef EX_NOUSER
7222 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007223#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007224#ifdef EX_NOHOST
7225 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007226#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007227#ifdef EX_UNAVAILABLE
7228 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007229#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007230#ifdef EX_SOFTWARE
7231 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007232#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007233#ifdef EX_OSERR
7234 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007235#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007236#ifdef EX_OSFILE
7237 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007238#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007239#ifdef EX_CANTCREAT
7240 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007241#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007242#ifdef EX_IOERR
7243 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007244#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007245#ifdef EX_TEMPFAIL
7246 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007247#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007248#ifdef EX_PROTOCOL
7249 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007250#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007251#ifdef EX_NOPERM
7252 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007253#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007254#ifdef EX_CONFIG
7255 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007256#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007257#ifdef EX_NOTFOUND
7258 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007259#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007260
Guido van Rossum246bc171999-02-01 23:54:31 +00007261#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007262#if defined(PYOS_OS2) && defined(PYCC_GCC)
7263 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7264 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7265 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7266 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7267 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7268 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7269 if (ins(d, "P_PM", (long)P_PM)) return -1;
7270 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7271 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7272 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7273 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7274 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7275 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7276 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7277 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7278 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7279 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7280 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7281 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7282 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7283#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007284 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7285 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7286 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7287 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7288 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007289#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007290#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007291
Guido van Rossumd48f2521997-12-05 22:19:34 +00007292#if defined(PYOS_OS2)
7293 if (insertvalues(d)) return -1;
7294#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007295 return 0;
7296}
7297
7298
Tim Peters5aa91602002-01-30 05:46:57 +00007299#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007300#define INITFUNC initnt
7301#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007302
7303#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007304#define INITFUNC initos2
7305#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007306
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007307#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007308#define INITFUNC initposix
7309#define MODNAME "posix"
7310#endif
7311
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007312PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007313INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007314{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007315 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007316
Fred Drake4d1e64b2002-04-15 19:40:07 +00007317 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007318 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007319 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00007320 if (m == NULL)
7321 return;
Tim Peters5aa91602002-01-30 05:46:57 +00007322
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007323 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007324 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007325 Py_XINCREF(v);
7326 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007327 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007328 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007329
Fred Drake4d1e64b2002-04-15 19:40:07 +00007330 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007331 return;
7332
Fred Drake4d1e64b2002-04-15 19:40:07 +00007333 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007334 return;
7335
Fred Drake4d1e64b2002-04-15 19:40:07 +00007336 Py_INCREF(PyExc_OSError);
7337 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007338
Guido van Rossumb3d39562000-01-31 18:41:26 +00007339#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007340 if (posix_putenv_garbage == NULL)
7341 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007342#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007343
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007344 if (!initialized) {
7345 stat_result_desc.name = MODNAME ".stat_result";
7346 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7347 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7348 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7349 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7350 structseq_new = StatResultType.tp_new;
7351 StatResultType.tp_new = statresult_new;
7352
7353 statvfs_result_desc.name = MODNAME ".statvfs_result";
7354 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
7355 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007356 Py_INCREF((PyObject*) &StatResultType);
7357 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007358 Py_INCREF((PyObject*) &StatVFSResultType);
7359 PyModule_AddObject(m, "statvfs_result",
7360 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007361 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007362
7363#ifdef __APPLE__
7364 /*
7365 * Step 2 of weak-linking support on Mac OS X.
7366 *
7367 * The code below removes functions that are not available on the
7368 * currently active platform.
7369 *
7370 * This block allow one to use a python binary that was build on
7371 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7372 * OSX 10.4.
7373 */
7374#ifdef HAVE_FSTATVFS
7375 if (fstatvfs == NULL) {
7376 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
7377 return;
7378 }
7379 }
7380#endif /* HAVE_FSTATVFS */
7381
7382#ifdef HAVE_STATVFS
7383 if (statvfs == NULL) {
7384 if (PyObject_DelAttrString(m, "statvfs") == -1) {
7385 return;
7386 }
7387 }
7388#endif /* HAVE_STATVFS */
7389
7390# ifdef HAVE_LCHOWN
7391 if (lchown == NULL) {
7392 if (PyObject_DelAttrString(m, "lchown") == -1) {
7393 return;
7394 }
7395 }
7396#endif /* HAVE_LCHOWN */
7397
7398
7399#endif /* __APPLE__ */
7400
Guido van Rossumb6775db1994-08-01 11:34:53 +00007401}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007402
7403#ifdef __cplusplus
7404}
7405#endif