blob: 1d1e299bbcaa460bfa79c2a8f904a75f486e0968 [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
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000334#if defined _MSC_VER && _MSC_VER >= 1400
335/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
336 * valid and throw an assertion if it isn't.
337 * Normally, an invalid fd is likely to be a C program error and therefore
338 * an assertion can be useful, but it does contradict the POSIX standard
339 * which for write(2) states:
340 * "Otherwise, -1 shall be returned and errno set to indicate the error."
341 * "[EBADF] The fildes argument is not a valid file descriptor open for
342 * writing."
343 * Furthermore, python allows the user to enter any old integer
344 * as a fd and should merely raise a python exception on error.
345 * The Microsoft CRT doesn't provide an official way to check for the
346 * validity of a file descriptor, but we can emulate its internal behaviour
347 * by using the exported __pinfo data member and knowledge of the
348 * internal structures involved.
349 * The structures below must be updated for each version of visual studio
350 * according to the file internal.h in the CRT source, until MS comes
351 * up with a less hacky way to do this.
352 * (all of this is to avoid globally modifying the CRT behaviour using
353 * _set_invalid_parameter_handler() and _CrtSetReportMode())
354 */
355#if _MSC_VER >= 1500 /* VS 2008 */
356typedef struct {
357 intptr_t osfhnd;
358 char osfile;
359 char pipech;
360 int lockinitflag;
361 CRITICAL_SECTION lock;
362#ifndef _SAFECRT_IMPL
363 char textmode : 7;
364 char unicode : 1;
365 char pipech2[2];
366 __int64 startpos;
367 BOOL utf8translations;
368 char dbcsBuffer;
369 BOOL dbcsBufferUsed;
370#endif /* _SAFECRT_IMPL */
371 } ioinfo;
372#elif _MSC_VER >= 1400 /* VS 2005 */
373typedef struct {
374 intptr_t osfhnd;
375 char osfile;
376 char pipech;
377 int lockinitflag;
378 CRITICAL_SECTION lock;
379#ifndef _SAFECRT_IMPL
380 char textmode : 7;
381 char unicode : 1;
382 char pipech2[2];
383 __int64 startpos;
384 BOOL utf8translations;
Kristján Valur Jónsson45ed72d2009-03-03 06:52:34 +0000385#ifndef _DEBUG
386 /* padding hack. 8 byte extra length observed at
387 * runtime, for 32 and 64 bits when not in _DEBUG
388 */
389 __int32 _padding[2];
390#endif
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000391#endif /* _SAFECRT_IMPL */
392 } ioinfo;
393#endif
394
395extern __declspec(dllimport) ioinfo * __pioinfo[];
396#define IOINFO_L2E 5
397#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
398#define IOINFO_ARRAYS 64
399#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
400#define FOPEN 0x01
401#define _NO_CONSOLE_FILENO (intptr_t)-2
402
403/* This function emulates what the windows CRT does to validate file handles */
404int
405_PyVerify_fd(int fd)
406{
407 const int i1 = fd >> IOINFO_L2E;
408 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
409
410 /* See that it isn't a special CLEAR fileno */
411 if (fd != _NO_CONSOLE_FILENO) {
412 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
413 * we check pointer validity and other info
414 */
415 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
416 /* finally, check that the file is open */
417 if (__pioinfo[i1][i2].osfile & FOPEN)
418 return 1;
419 }
420 }
421 errno = EBADF;
422 return 0;
423}
424
425/* the special case of checking dup2. The target fd must be in a sensible range */
426static int
427_PyVerify_fd_dup2(int fd1, int fd2)
428{
429 if (!_PyVerify_fd(fd1))
430 return 0;
431 if (fd2 == _NO_CONSOLE_FILENO)
432 return 0;
433 if ((unsigned)fd2 < _NHANDLE_)
434 return 1;
435 else
436 return 0;
437}
438#else
439/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
440#define _PyVerify_fd_dup2(A, B) (1)
441#endif
442
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000443/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000444#ifdef WITH_NEXT_FRAMEWORK
445/* On Darwin/MacOSX a shared library or framework has no access to
446** environ directly, we must obtain it with _NSGetEnviron().
447*/
448#include <crt_externs.h>
449static char **environ;
450#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000451extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000452#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453
Barry Warsaw53699e91996-12-10 23:23:01 +0000454static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000455convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000456{
Barry Warsaw53699e91996-12-10 23:23:01 +0000457 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000458#ifdef MS_WINDOWS
459 wchar_t **e;
460#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000461 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000462#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000463 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000464 if (d == NULL)
465 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000466#ifdef WITH_NEXT_FRAMEWORK
467 if (environ == NULL)
468 environ = *_NSGetEnviron();
469#endif
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000470#ifdef MS_WINDOWS
471 /* _wenviron must be initialized in this way if the program is started
472 through main() instead of wmain(). */
473 _wgetenv(L"");
474 if (_wenviron == NULL)
475 return d;
476 /* This part ignores errors */
477 for (e = _wenviron; *e != NULL; e++) {
478 PyObject *k;
479 PyObject *v;
480 wchar_t *p = wcschr(*e, L'=');
481 if (p == NULL)
482 continue;
483 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
484 if (k == NULL) {
485 PyErr_Clear();
486 continue;
487 }
488 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
489 if (v == NULL) {
490 PyErr_Clear();
491 Py_DECREF(k);
492 continue;
493 }
494 if (PyDict_GetItem(d, k) == NULL) {
495 if (PyDict_SetItem(d, k, v) != 0)
496 PyErr_Clear();
497 }
498 Py_DECREF(k);
499 Py_DECREF(v);
500 }
501#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502 if (environ == NULL)
503 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000504 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000505 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000506 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000507 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000508 char *p = strchr(*e, '=');
509 if (p == NULL)
510 continue;
Guido van Rossum98297ee2007-11-06 21:34:58 +0000511 k = PyUnicode_FromStringAndSize(*e, (int)(p-*e));
Guido van Rossum6a619f41999-08-03 19:41:10 +0000512 if (k == NULL) {
513 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000514 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000515 }
Guido van Rossum98297ee2007-11-06 21:34:58 +0000516 v = PyUnicode_FromString(p+1);
Guido van Rossum6a619f41999-08-03 19:41:10 +0000517 if (v == NULL) {
518 PyErr_Clear();
519 Py_DECREF(k);
520 continue;
521 }
522 if (PyDict_GetItem(d, k) == NULL) {
523 if (PyDict_SetItem(d, k, v) != 0)
524 PyErr_Clear();
525 }
526 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000527 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000528 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000529#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000530#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000531 {
532 APIRET rc;
533 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
534
535 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000536 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Christian Heimes72b710a2008-05-26 13:28:38 +0000537 PyObject *v = PyBytes_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000538 PyDict_SetItemString(d, "BEGINLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000539 Py_DECREF(v);
540 }
541 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
542 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
Christian Heimes72b710a2008-05-26 13:28:38 +0000543 PyObject *v = PyBytes_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000544 PyDict_SetItemString(d, "ENDLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000545 Py_DECREF(v);
546 }
547 }
548#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000549 return d;
550}
551
552
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000553/* Set a POSIX-specific error from errno, and return NULL */
554
Barry Warsawd58d7641998-07-23 16:14:40 +0000555static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000556posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000557{
Barry Warsawca74da41999-02-09 19:31:45 +0000558 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000559}
Barry Warsawd58d7641998-07-23 16:14:40 +0000560static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000561posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000562{
Barry Warsawca74da41999-02-09 19:31:45 +0000563 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000564}
565
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000566#ifdef Py_WIN_WIDE_FILENAMES
567static PyObject *
568posix_error_with_unicode_filename(Py_UNICODE* name)
569{
570 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
571}
572#endif /* Py_WIN_WIDE_FILENAMES */
573
574
Mark Hammondef8b6542001-05-13 08:04:26 +0000575static PyObject *
576posix_error_with_allocated_filename(char* name)
577{
578 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
579 PyMem_Free(name);
580 return rc;
581}
582
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000583#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000584static PyObject *
585win32_error(char* function, char* filename)
586{
Mark Hammond33a6da92000-08-15 00:46:38 +0000587 /* XXX We should pass the function name along in the future.
Georg Brandl38feaf02008-05-25 07:45:51 +0000588 (winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000589 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000590 Windows error object, which is non-trivial.
591 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000592 errno = GetLastError();
593 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000594 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000595 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000596 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000597}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000598
599#ifdef Py_WIN_WIDE_FILENAMES
600static PyObject *
601win32_error_unicode(char* function, Py_UNICODE* filename)
602{
603 /* XXX - see win32_error for comments on 'function' */
604 errno = GetLastError();
605 if (filename)
606 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
607 else
608 return PyErr_SetFromWindowsErr(errno);
609}
610
Thomas Wouters477c8d52006-05-27 19:21:47 +0000611static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000612convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000613{
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000614 if (PyUnicode_CheckExact(*param))
615 Py_INCREF(*param);
616 else if (PyUnicode_Check(*param))
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000617 /* For a Unicode subtype that's not a Unicode object,
618 return a true Unicode object with the same data. */
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000619 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
620 PyUnicode_GET_SIZE(*param));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000621 else
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000622 *param = PyUnicode_FromEncodedObject(*param,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000623 Py_FileSystemDefaultEncoding,
624 "strict");
625 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000626}
627
628#endif /* Py_WIN_WIDE_FILENAMES */
629
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000630#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000631
Guido van Rossumd48f2521997-12-05 22:19:34 +0000632#if defined(PYOS_OS2)
633/**********************************************************************
634 * Helper Function to Trim and Format OS/2 Messages
635 **********************************************************************/
636 static void
637os2_formatmsg(char *msgbuf, int msglen, char *reason)
638{
639 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
640
641 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
642 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
643
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000644 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000645 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
646 }
647
648 /* Add Optional Reason Text */
649 if (reason) {
650 strcat(msgbuf, " : ");
651 strcat(msgbuf, reason);
652 }
653}
654
655/**********************************************************************
656 * Decode an OS/2 Operating System Error Code
657 *
658 * A convenience function to lookup an OS/2 error code and return a
659 * text message we can use to raise a Python exception.
660 *
661 * Notes:
662 * The messages for errors returned from the OS/2 kernel reside in
663 * the file OSO001.MSG in the \OS2 directory hierarchy.
664 *
665 **********************************************************************/
666 static char *
667os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
668{
669 APIRET rc;
670 ULONG msglen;
671
672 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
673 Py_BEGIN_ALLOW_THREADS
674 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
675 errorcode, "oso001.msg", &msglen);
676 Py_END_ALLOW_THREADS
677
678 if (rc == NO_ERROR)
679 os2_formatmsg(msgbuf, msglen, reason);
680 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000681 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000682 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000683
684 return msgbuf;
685}
686
687/* Set an OS/2-specific error and return NULL. OS/2 kernel
688 errors are not in a global variable e.g. 'errno' nor are
689 they congruent with posix error numbers. */
690
691static PyObject * os2_error(int code)
692{
693 char text[1024];
694 PyObject *v;
695
696 os2_strerror(text, sizeof(text), code, "");
697
698 v = Py_BuildValue("(is)", code, text);
699 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000700 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000701 Py_DECREF(v);
702 }
703 return NULL; /* Signal to Python that an Exception is Pending */
704}
705
706#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000707
708/* POSIX generic methods */
709
Barry Warsaw53699e91996-12-10 23:23:01 +0000710static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000711posix_fildes(PyObject *fdobj, int (*func)(int))
712{
713 int fd;
714 int res;
715 fd = PyObject_AsFileDescriptor(fdobj);
716 if (fd < 0)
717 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000718 if (!_PyVerify_fd(fd))
719 return posix_error();
Fred Drake4d1e64b2002-04-15 19:40:07 +0000720 Py_BEGIN_ALLOW_THREADS
721 res = (*func)(fd);
722 Py_END_ALLOW_THREADS
723 if (res < 0)
724 return posix_error();
725 Py_INCREF(Py_None);
726 return Py_None;
727}
Guido van Rossum21142a01999-01-08 21:05:37 +0000728
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000729#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000730static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000731unicode_file_names(void)
732{
733 static int canusewide = -1;
734 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000735 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000736 the Windows NT family. */
737 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
738 }
739 return canusewide;
740}
741#endif
Tim Peters11b23062003-04-23 02:39:17 +0000742
Guido van Rossum21142a01999-01-08 21:05:37 +0000743static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000744posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000745{
Mark Hammondef8b6542001-05-13 08:04:26 +0000746 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000747 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000748 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000749 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000750 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000751 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000752 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000753 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000754 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000755 return posix_error_with_allocated_filename(path1);
756 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000757 Py_INCREF(Py_None);
758 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000759}
760
Barry Warsaw53699e91996-12-10 23:23:01 +0000761static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000762posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000763 char *format,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000764 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000765{
Mark Hammondef8b6542001-05-13 08:04:26 +0000766 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000767 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000768 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000769 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000770 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000771 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000772 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000773 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000774 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000775 PyMem_Free(path1);
776 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000777 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000778 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000779 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000780 Py_INCREF(Py_None);
781 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000782}
783
Thomas Wouters477c8d52006-05-27 19:21:47 +0000784#ifdef Py_WIN_WIDE_FILENAMES
785static PyObject*
786win32_1str(PyObject* args, char* func,
787 char* format, BOOL (__stdcall *funcA)(LPCSTR),
788 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
789{
790 PyObject *uni;
791 char *ansi;
792 BOOL result;
793 if (unicode_file_names()) {
794 if (!PyArg_ParseTuple(args, wformat, &uni))
795 PyErr_Clear();
796 else {
797 Py_BEGIN_ALLOW_THREADS
798 result = funcW(PyUnicode_AsUnicode(uni));
799 Py_END_ALLOW_THREADS
800 if (!result)
801 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
802 Py_INCREF(Py_None);
803 return Py_None;
804 }
805 }
806 if (!PyArg_ParseTuple(args, format, &ansi))
807 return NULL;
808 Py_BEGIN_ALLOW_THREADS
809 result = funcA(ansi);
810 Py_END_ALLOW_THREADS
811 if (!result)
812 return win32_error(func, ansi);
813 Py_INCREF(Py_None);
814 return Py_None;
815
816}
817
818/* This is a reimplementation of the C library's chdir function,
819 but one that produces Win32 errors instead of DOS error codes.
820 chdir is essentially a wrapper around SetCurrentDirectory; however,
821 it also needs to set "magic" environment variables indicating
822 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000823static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000824win32_chdir(LPCSTR path)
825{
826 char new_path[MAX_PATH+1];
827 int result;
828 char env[4] = "=x:";
829
830 if(!SetCurrentDirectoryA(path))
831 return FALSE;
832 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
833 if (!result)
834 return FALSE;
835 /* In the ANSI API, there should not be any paths longer
836 than MAX_PATH. */
837 assert(result <= MAX_PATH+1);
838 if (strncmp(new_path, "\\\\", 2) == 0 ||
839 strncmp(new_path, "//", 2) == 0)
840 /* UNC path, nothing to do. */
841 return TRUE;
842 env[1] = new_path[0];
843 return SetEnvironmentVariableA(env, new_path);
844}
845
846/* The Unicode version differs from the ANSI version
847 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000848static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000849win32_wchdir(LPCWSTR path)
850{
851 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
852 int result;
853 wchar_t env[4] = L"=x:";
854
855 if(!SetCurrentDirectoryW(path))
856 return FALSE;
857 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
858 if (!result)
859 return FALSE;
860 if (result > MAX_PATH+1) {
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000861 new_path = malloc(result * sizeof(wchar_t));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000862 if (!new_path) {
863 SetLastError(ERROR_OUTOFMEMORY);
864 return FALSE;
865 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000866 result = GetCurrentDirectoryW(result, new_path);
867 if (!result) {
868 free(new_path);
869 return FALSE;
870 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000871 }
872 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
873 wcsncmp(new_path, L"//", 2) == 0)
874 /* UNC path, nothing to do. */
875 return TRUE;
876 env[1] = new_path[0];
877 result = SetEnvironmentVariableW(env, new_path);
878 if (new_path != _new_path)
879 free(new_path);
880 return result;
881}
882#endif
883
Martin v. Löwis14694662006-02-03 12:54:16 +0000884#ifdef MS_WINDOWS
885/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
886 - time stamps are restricted to second resolution
887 - file modification times suffer from forth-and-back conversions between
888 UTC and local time
889 Therefore, we implement our own stat, based on the Win32 API directly.
890*/
891#define HAVE_STAT_NSEC 1
892
893struct win32_stat{
894 int st_dev;
895 __int64 st_ino;
896 unsigned short st_mode;
897 int st_nlink;
898 int st_uid;
899 int st_gid;
900 int st_rdev;
901 __int64 st_size;
902 int st_atime;
903 int st_atime_nsec;
904 int st_mtime;
905 int st_mtime_nsec;
906 int st_ctime;
907 int st_ctime_nsec;
908};
909
910static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
911
912static void
913FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
914{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000915 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
916 /* Cannot simply cast and dereference in_ptr,
917 since it might not be aligned properly */
918 __int64 in;
919 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000920 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
921 /* XXX Win32 supports time stamps past 2038; we currently don't */
922 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
923}
924
Thomas Wouters477c8d52006-05-27 19:21:47 +0000925static void
926time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
927{
928 /* XXX endianness */
929 __int64 out;
930 out = time_in + secs_between_epochs;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000931 out = out * 10000000 + nsec_in / 100;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000932 memcpy(out_ptr, &out, sizeof(out));
933}
934
Martin v. Löwis14694662006-02-03 12:54:16 +0000935/* Below, we *know* that ugo+r is 0444 */
936#if _S_IREAD != 0400
937#error Unsupported C library
938#endif
939static int
940attributes_to_mode(DWORD attr)
941{
942 int m = 0;
943 if (attr & FILE_ATTRIBUTE_DIRECTORY)
944 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
945 else
946 m |= _S_IFREG;
947 if (attr & FILE_ATTRIBUTE_READONLY)
948 m |= 0444;
949 else
950 m |= 0666;
951 return m;
952}
953
954static int
955attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
956{
957 memset(result, 0, sizeof(*result));
958 result->st_mode = attributes_to_mode(info->dwFileAttributes);
959 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
960 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
961 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
962 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
963
964 return 0;
965}
966
Thomas Wouters89f507f2006-12-13 04:49:30 +0000967/* Emulate GetFileAttributesEx[AW] on Windows 95 */
968static int checked = 0;
969static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
970static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
971static void
972check_gfax()
973{
974 HINSTANCE hKernel32;
975 if (checked)
976 return;
977 checked = 1;
978 hKernel32 = GetModuleHandle("KERNEL32");
979 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
980 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
981}
982
Guido van Rossumd8faa362007-04-27 19:54:29 +0000983static BOOL
984attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
985{
986 HANDLE hFindFile;
987 WIN32_FIND_DATAA FileData;
988 hFindFile = FindFirstFileA(pszFile, &FileData);
989 if (hFindFile == INVALID_HANDLE_VALUE)
990 return FALSE;
991 FindClose(hFindFile);
992 pfad->dwFileAttributes = FileData.dwFileAttributes;
993 pfad->ftCreationTime = FileData.ftCreationTime;
994 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
995 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
996 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
997 pfad->nFileSizeLow = FileData.nFileSizeLow;
998 return TRUE;
999}
1000
1001static BOOL
1002attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1003{
1004 HANDLE hFindFile;
1005 WIN32_FIND_DATAW FileData;
1006 hFindFile = FindFirstFileW(pszFile, &FileData);
1007 if (hFindFile == INVALID_HANDLE_VALUE)
1008 return FALSE;
1009 FindClose(hFindFile);
1010 pfad->dwFileAttributes = FileData.dwFileAttributes;
1011 pfad->ftCreationTime = FileData.ftCreationTime;
1012 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1013 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1014 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1015 pfad->nFileSizeLow = FileData.nFileSizeLow;
1016 return TRUE;
1017}
1018
Thomas Wouters89f507f2006-12-13 04:49:30 +00001019static BOOL WINAPI
1020Py_GetFileAttributesExA(LPCSTR pszFile,
1021 GET_FILEEX_INFO_LEVELS level,
1022 LPVOID pv)
1023{
1024 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00001025 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1026 /* First try to use the system's implementation, if that is
1027 available and either succeeds to gives an error other than
1028 that it isn't implemented. */
1029 check_gfax();
1030 if (gfaxa) {
1031 result = gfaxa(pszFile, level, pv);
1032 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1033 return result;
1034 }
1035 /* It's either not present, or not implemented.
1036 Emulate using FindFirstFile. */
1037 if (level != GetFileExInfoStandard) {
1038 SetLastError(ERROR_INVALID_PARAMETER);
1039 return FALSE;
1040 }
1041 /* Use GetFileAttributes to validate that the file name
1042 does not contain wildcards (which FindFirstFile would
1043 accept). */
1044 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
1045 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001046 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001047}
1048
1049static BOOL WINAPI
1050Py_GetFileAttributesExW(LPCWSTR pszFile,
1051 GET_FILEEX_INFO_LEVELS level,
1052 LPVOID pv)
1053{
1054 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00001055 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1056 /* First try to use the system's implementation, if that is
1057 available and either succeeds to gives an error other than
1058 that it isn't implemented. */
1059 check_gfax();
1060 if (gfaxa) {
1061 result = gfaxw(pszFile, level, pv);
1062 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1063 return result;
1064 }
1065 /* It's either not present, or not implemented.
1066 Emulate using FindFirstFile. */
1067 if (level != GetFileExInfoStandard) {
1068 SetLastError(ERROR_INVALID_PARAMETER);
1069 return FALSE;
1070 }
1071 /* Use GetFileAttributes to validate that the file name
1072 does not contain wildcards (which FindFirstFile would
1073 accept). */
1074 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1075 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001076 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001077}
1078
Martin v. Löwis14694662006-02-03 12:54:16 +00001079static int
1080win32_stat(const char* path, struct win32_stat *result)
1081{
1082 WIN32_FILE_ATTRIBUTE_DATA info;
1083 int code;
1084 char *dot;
1085 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001086 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001087 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1088 /* Protocol violation: we explicitly clear errno, instead of
1089 setting it to a POSIX error. Callers should use GetLastError. */
1090 errno = 0;
1091 return -1;
1092 } else {
1093 /* Could not get attributes on open file. Fall back to
1094 reading the directory. */
1095 if (!attributes_from_dir(path, &info)) {
1096 /* Very strange. This should not fail now */
1097 errno = 0;
1098 return -1;
1099 }
1100 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001101 }
1102 code = attribute_data_to_stat(&info, result);
1103 if (code != 0)
1104 return code;
1105 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1106 dot = strrchr(path, '.');
1107 if (dot) {
1108 if (stricmp(dot, ".bat") == 0 ||
1109 stricmp(dot, ".cmd") == 0 ||
1110 stricmp(dot, ".exe") == 0 ||
1111 stricmp(dot, ".com") == 0)
1112 result->st_mode |= 0111;
1113 }
1114 return code;
1115}
1116
1117static int
1118win32_wstat(const wchar_t* path, struct win32_stat *result)
1119{
1120 int code;
1121 const wchar_t *dot;
1122 WIN32_FILE_ATTRIBUTE_DATA info;
1123 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001124 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001125 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1126 /* Protocol violation: we explicitly clear errno, instead of
1127 setting it to a POSIX error. Callers should use GetLastError. */
1128 errno = 0;
1129 return -1;
1130 } else {
1131 /* Could not get attributes on open file. Fall back to
1132 reading the directory. */
1133 if (!attributes_from_dir_w(path, &info)) {
1134 /* Very strange. This should not fail now */
1135 errno = 0;
1136 return -1;
1137 }
1138 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001139 }
1140 code = attribute_data_to_stat(&info, result);
1141 if (code < 0)
1142 return code;
1143 /* Set IFEXEC if it is an .exe, .bat, ... */
1144 dot = wcsrchr(path, '.');
1145 if (dot) {
1146 if (_wcsicmp(dot, L".bat") == 0 ||
1147 _wcsicmp(dot, L".cmd") == 0 ||
1148 _wcsicmp(dot, L".exe") == 0 ||
1149 _wcsicmp(dot, L".com") == 0)
1150 result->st_mode |= 0111;
1151 }
1152 return code;
1153}
1154
1155static int
1156win32_fstat(int file_number, struct win32_stat *result)
1157{
1158 BY_HANDLE_FILE_INFORMATION info;
1159 HANDLE h;
1160 int type;
1161
1162 h = (HANDLE)_get_osfhandle(file_number);
1163
1164 /* Protocol violation: we explicitly clear errno, instead of
1165 setting it to a POSIX error. Callers should use GetLastError. */
1166 errno = 0;
1167
1168 if (h == INVALID_HANDLE_VALUE) {
1169 /* This is really a C library error (invalid file handle).
1170 We set the Win32 error to the closes one matching. */
1171 SetLastError(ERROR_INVALID_HANDLE);
1172 return -1;
1173 }
1174 memset(result, 0, sizeof(*result));
1175
1176 type = GetFileType(h);
1177 if (type == FILE_TYPE_UNKNOWN) {
1178 DWORD error = GetLastError();
1179 if (error != 0) {
1180 return -1;
1181 }
1182 /* else: valid but unknown file */
1183 }
1184
1185 if (type != FILE_TYPE_DISK) {
1186 if (type == FILE_TYPE_CHAR)
1187 result->st_mode = _S_IFCHR;
1188 else if (type == FILE_TYPE_PIPE)
1189 result->st_mode = _S_IFIFO;
1190 return 0;
1191 }
1192
1193 if (!GetFileInformationByHandle(h, &info)) {
1194 return -1;
1195 }
1196
1197 /* similar to stat() */
1198 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1199 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1200 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1201 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1202 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1203 /* specific to fstat() */
1204 result->st_nlink = info.nNumberOfLinks;
1205 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1206 return 0;
1207}
1208
1209#endif /* MS_WINDOWS */
1210
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001211PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001212"stat_result: Result from stat or lstat.\n\n\
1213This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001214 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001215or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1216\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001217Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1218or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001219\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001220See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001221
1222static PyStructSequence_Field stat_result_fields[] = {
1223 {"st_mode", "protection bits"},
1224 {"st_ino", "inode"},
1225 {"st_dev", "device"},
1226 {"st_nlink", "number of hard links"},
1227 {"st_uid", "user ID of owner"},
1228 {"st_gid", "group ID of owner"},
1229 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001230 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1231 {NULL, "integer time of last access"},
1232 {NULL, "integer time of last modification"},
1233 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001234 {"st_atime", "time of last access"},
1235 {"st_mtime", "time of last modification"},
1236 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001237#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001238 {"st_blksize", "blocksize for filesystem I/O"},
1239#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001240#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001241 {"st_blocks", "number of blocks allocated"},
1242#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001243#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001244 {"st_rdev", "device type (if inode device)"},
1245#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001246#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1247 {"st_flags", "user defined flags for file"},
1248#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001249#ifdef HAVE_STRUCT_STAT_ST_GEN
1250 {"st_gen", "generation number"},
1251#endif
1252#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1253 {"st_birthtime", "time of creation"},
1254#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001255 {0}
1256};
1257
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001258#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001259#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001260#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001261#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001262#endif
1263
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001264#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001265#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1266#else
1267#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1268#endif
1269
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001270#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001271#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1272#else
1273#define ST_RDEV_IDX ST_BLOCKS_IDX
1274#endif
1275
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001276#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1277#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1278#else
1279#define ST_FLAGS_IDX ST_RDEV_IDX
1280#endif
1281
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001282#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001283#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001284#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001285#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001286#endif
1287
1288#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1289#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1290#else
1291#define ST_BIRTHTIME_IDX ST_GEN_IDX
1292#endif
1293
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001294static PyStructSequence_Desc stat_result_desc = {
1295 "stat_result", /* name */
1296 stat_result__doc__, /* doc */
1297 stat_result_fields,
1298 10
1299};
1300
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001301PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001302"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1303This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001304 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001305or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001306\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001307See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001308
1309static PyStructSequence_Field statvfs_result_fields[] = {
1310 {"f_bsize", },
1311 {"f_frsize", },
1312 {"f_blocks", },
1313 {"f_bfree", },
1314 {"f_bavail", },
1315 {"f_files", },
1316 {"f_ffree", },
1317 {"f_favail", },
1318 {"f_flag", },
1319 {"f_namemax",},
1320 {0}
1321};
1322
1323static PyStructSequence_Desc statvfs_result_desc = {
1324 "statvfs_result", /* name */
1325 statvfs_result__doc__, /* doc */
1326 statvfs_result_fields,
1327 10
1328};
1329
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001330static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001331static PyTypeObject StatResultType;
1332static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001333static newfunc structseq_new;
1334
1335static PyObject *
1336statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1337{
1338 PyStructSequence *result;
1339 int i;
1340
1341 result = (PyStructSequence*)structseq_new(type, args, kwds);
1342 if (!result)
1343 return NULL;
1344 /* If we have been initialized from a tuple,
1345 st_?time might be set to None. Initialize it
1346 from the int slots. */
1347 for (i = 7; i <= 9; i++) {
1348 if (result->ob_item[i+3] == Py_None) {
1349 Py_DECREF(Py_None);
1350 Py_INCREF(result->ob_item[i]);
1351 result->ob_item[i+3] = result->ob_item[i];
1352 }
1353 }
1354 return (PyObject*)result;
1355}
1356
1357
1358
1359/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001360static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001361
1362PyDoc_STRVAR(stat_float_times__doc__,
1363"stat_float_times([newval]) -> oldval\n\n\
1364Determine whether os.[lf]stat represents time stamps as float objects.\n\
1365If newval is True, future calls to stat() return floats, if it is False,\n\
1366future calls return ints. \n\
1367If newval is omitted, return the current setting.\n");
1368
1369static PyObject*
1370stat_float_times(PyObject* self, PyObject *args)
1371{
1372 int newval = -1;
1373 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1374 return NULL;
1375 if (newval == -1)
1376 /* Return old value */
1377 return PyBool_FromLong(_stat_float_times);
1378 _stat_float_times = newval;
1379 Py_INCREF(Py_None);
1380 return Py_None;
1381}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001382
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001383static void
1384fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1385{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001386 PyObject *fval,*ival;
1387#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001388 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001389#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001390 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001391#endif
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001392 if (!ival)
1393 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001394 if (_stat_float_times) {
1395 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1396 } else {
1397 fval = ival;
1398 Py_INCREF(fval);
1399 }
1400 PyStructSequence_SET_ITEM(v, index, ival);
1401 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001402}
1403
Tim Peters5aa91602002-01-30 05:46:57 +00001404/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001405 (used by posix_stat() and posix_fstat()) */
1406static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001407_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001408{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001409 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001410 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001411 if (v == NULL)
1412 return NULL;
1413
Christian Heimes217cfd12007-12-02 14:31:20 +00001414 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001415#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001416 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001417 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001418#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001419 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001420#endif
1421#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001422 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001423 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001424#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001425 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001426#endif
Christian Heimes217cfd12007-12-02 14:31:20 +00001427 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1428 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1429 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001430#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001431 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001432 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001433#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001434 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001435#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001436
Martin v. Löwis14694662006-02-03 12:54:16 +00001437#if defined(HAVE_STAT_TV_NSEC)
1438 ansec = st->st_atim.tv_nsec;
1439 mnsec = st->st_mtim.tv_nsec;
1440 cnsec = st->st_ctim.tv_nsec;
1441#elif defined(HAVE_STAT_TV_NSEC2)
1442 ansec = st->st_atimespec.tv_nsec;
1443 mnsec = st->st_mtimespec.tv_nsec;
1444 cnsec = st->st_ctimespec.tv_nsec;
1445#elif defined(HAVE_STAT_NSEC)
1446 ansec = st->st_atime_nsec;
1447 mnsec = st->st_mtime_nsec;
1448 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001449#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001450 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001451#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001452 fill_time(v, 7, st->st_atime, ansec);
1453 fill_time(v, 8, st->st_mtime, mnsec);
1454 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001455
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001456#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001457 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001458 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001459#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001460#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001461 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001462 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001463#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001464#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001465 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001466 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001467#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001468#ifdef HAVE_STRUCT_STAT_ST_GEN
1469 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001470 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001471#endif
1472#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1473 {
1474 PyObject *val;
1475 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001476 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001477#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001478 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001479#else
1480 bnsec = 0;
1481#endif
1482 if (_stat_float_times) {
1483 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1484 } else {
Christian Heimes217cfd12007-12-02 14:31:20 +00001485 val = PyLong_FromLong((long)bsec);
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001486 }
1487 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1488 val);
1489 }
1490#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001491#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1492 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001493 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001494#endif
Fred Drake699f3522000-06-29 21:12:41 +00001495
1496 if (PyErr_Occurred()) {
1497 Py_DECREF(v);
1498 return NULL;
1499 }
1500
1501 return v;
1502}
1503
Martin v. Löwisd8948722004-06-02 09:57:56 +00001504#ifdef MS_WINDOWS
1505
1506/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1507 where / can be used in place of \ and the trailing slash is optional.
1508 Both SERVER and SHARE must have at least one character.
1509*/
1510
1511#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1512#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001513#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001514#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001515#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001516
Tim Peters4ad82172004-08-30 17:02:04 +00001517static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001518IsUNCRootA(char *path, int pathlen)
1519{
1520 #define ISSLASH ISSLASHA
1521
1522 int i, share;
1523
1524 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1525 /* minimum UNCRoot is \\x\y */
1526 return FALSE;
1527 for (i = 2; i < pathlen ; i++)
1528 if (ISSLASH(path[i])) break;
1529 if (i == 2 || i == pathlen)
1530 /* do not allow \\\SHARE or \\SERVER */
1531 return FALSE;
1532 share = i+1;
1533 for (i = share; i < pathlen; i++)
1534 if (ISSLASH(path[i])) break;
1535 return (i != share && (i == pathlen || i == pathlen-1));
1536
1537 #undef ISSLASH
1538}
1539
1540#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001541static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001542IsUNCRootW(Py_UNICODE *path, int pathlen)
1543{
1544 #define ISSLASH ISSLASHW
1545
1546 int i, share;
1547
1548 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1549 /* minimum UNCRoot is \\x\y */
1550 return FALSE;
1551 for (i = 2; i < pathlen ; i++)
1552 if (ISSLASH(path[i])) break;
1553 if (i == 2 || i == pathlen)
1554 /* do not allow \\\SHARE or \\SERVER */
1555 return FALSE;
1556 share = i+1;
1557 for (i = share; i < pathlen; i++)
1558 if (ISSLASH(path[i])) break;
1559 return (i != share && (i == pathlen || i == pathlen-1));
1560
1561 #undef ISSLASH
1562}
1563#endif /* Py_WIN_WIDE_FILENAMES */
1564#endif /* MS_WINDOWS */
1565
Barry Warsaw53699e91996-12-10 23:23:01 +00001566static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001567posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001568 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001569#ifdef __VMS
1570 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1571#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001572 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001573#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001574 char *wformat,
1575 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001576{
Fred Drake699f3522000-06-29 21:12:41 +00001577 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001578 char *path = NULL; /* pass this to stat; do not free() it */
1579 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001580 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001581 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001582
1583#ifdef Py_WIN_WIDE_FILENAMES
1584 /* If on wide-character-capable OS see if argument
1585 is Unicode and if so use wide API. */
1586 if (unicode_file_names()) {
1587 PyUnicodeObject *po;
1588 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001589 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1590
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001591 Py_BEGIN_ALLOW_THREADS
1592 /* PyUnicode_AS_UNICODE result OK without
1593 thread lock as it is a simple dereference. */
1594 res = wstatfunc(wpath, &st);
1595 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001596
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001597 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001598 return win32_error_unicode("stat", wpath);
1599 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001600 }
1601 /* Drop the argument parsing error as narrow strings
1602 are also valid. */
1603 PyErr_Clear();
1604 }
1605#endif
1606
Tim Peters5aa91602002-01-30 05:46:57 +00001607 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001608 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001609 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001610 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001611
Barry Warsaw53699e91996-12-10 23:23:01 +00001612 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001613 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001614 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001615
1616 if (res != 0) {
1617#ifdef MS_WINDOWS
1618 result = win32_error("stat", pathfree);
1619#else
1620 result = posix_error_with_filename(pathfree);
1621#endif
1622 }
1623 else
1624 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001625
Tim Peters500bd032001-12-19 19:05:01 +00001626 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001627 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001628}
1629
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001630/* POSIX methods */
1631
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001632PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001633"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001634Use the real uid/gid to test for access to a path. Note that most\n\
1635operations will use the effective uid/gid, therefore this routine can\n\
1636be used in a suid/sgid environment to test if the invoking user has the\n\
1637specified access to the path. The mode argument can be F_OK to test\n\
1638existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001639
1640static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001641posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001642{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001643 char *path;
1644 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001645
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001646#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001647 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001648 if (unicode_file_names()) {
1649 PyUnicodeObject *po;
1650 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1651 Py_BEGIN_ALLOW_THREADS
1652 /* PyUnicode_AS_UNICODE OK without thread lock as
1653 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001654 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001655 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001656 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001657 }
1658 /* Drop the argument parsing error as narrow strings
1659 are also valid. */
1660 PyErr_Clear();
1661 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001662 if (!PyArg_ParseTuple(args, "eti:access",
1663 Py_FileSystemDefaultEncoding, &path, &mode))
1664 return 0;
1665 Py_BEGIN_ALLOW_THREADS
1666 attr = GetFileAttributesA(path);
1667 Py_END_ALLOW_THREADS
1668 PyMem_Free(path);
1669finish:
1670 if (attr == 0xFFFFFFFF)
1671 /* File does not exist, or cannot read attributes */
1672 return PyBool_FromLong(0);
1673 /* Access is possible if either write access wasn't requested, or
Guido van Rossumb00324f2007-12-04 01:13:14 +00001674 the file isn't read-only, or if it's a directory, as there are
1675 no read-only directories on Windows. */
1676 return PyBool_FromLong(!(mode & 2)
1677 || !(attr & FILE_ATTRIBUTE_READONLY)
1678 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001679#else
1680 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001681 if (!PyArg_ParseTuple(args, "eti:access",
1682 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001683 return NULL;
1684 Py_BEGIN_ALLOW_THREADS
1685 res = access(path, mode);
1686 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001687 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001688 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001689#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001690}
1691
Guido van Rossumd371ff11999-01-25 16:12:23 +00001692#ifndef F_OK
1693#define F_OK 0
1694#endif
1695#ifndef R_OK
1696#define R_OK 4
1697#endif
1698#ifndef W_OK
1699#define W_OK 2
1700#endif
1701#ifndef X_OK
1702#define X_OK 1
1703#endif
1704
1705#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001706PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001707"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001708Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001709
1710static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001711posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001712{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001713 int id;
1714 char *ret;
1715
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001716 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001717 return NULL;
1718
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001719#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001720 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001721 if (id == 0) {
1722 ret = ttyname();
1723 }
1724 else {
1725 ret = NULL;
1726 }
1727#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001728 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001729#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001730 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001731 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001732 return PyUnicode_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001733}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001734#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001735
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001736#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001737PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001738"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001739Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001740
1741static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001742posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001743{
1744 char *ret;
1745 char buffer[L_ctermid];
1746
Greg Wardb48bc172000-03-01 21:51:56 +00001747#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001748 ret = ctermid_r(buffer);
1749#else
1750 ret = ctermid(buffer);
1751#endif
1752 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001753 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001754 return PyUnicode_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001755}
1756#endif
1757
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001758PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001759"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001760Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001761
Barry Warsaw53699e91996-12-10 23:23:01 +00001762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001763posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001764{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001765#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00001766 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001767#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001768 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001769#elif defined(__VMS)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001770 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001771#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001772 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001773#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001774}
1775
Fred Drake4d1e64b2002-04-15 19:40:07 +00001776#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001777PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001778"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001779Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001780opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001781
1782static PyObject *
1783posix_fchdir(PyObject *self, PyObject *fdobj)
1784{
1785 return posix_fildes(fdobj, fchdir);
1786}
1787#endif /* HAVE_FCHDIR */
1788
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001789
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001790PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001791"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001792Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001793
Barry Warsaw53699e91996-12-10 23:23:01 +00001794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001795posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001796{
Mark Hammondef8b6542001-05-13 08:04:26 +00001797 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001798 int i;
1799 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001800#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001801 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001802 if (unicode_file_names()) {
1803 PyUnicodeObject *po;
1804 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1805 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001806 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1807 if (attr != 0xFFFFFFFF) {
1808 if (i & _S_IWRITE)
1809 attr &= ~FILE_ATTRIBUTE_READONLY;
1810 else
1811 attr |= FILE_ATTRIBUTE_READONLY;
1812 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1813 }
1814 else
1815 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001816 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001817 if (!res)
1818 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001819 PyUnicode_AS_UNICODE(po));
1820 Py_INCREF(Py_None);
1821 return Py_None;
1822 }
1823 /* Drop the argument parsing error as narrow strings
1824 are also valid. */
1825 PyErr_Clear();
1826 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001827 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1828 &path, &i))
1829 return NULL;
1830 Py_BEGIN_ALLOW_THREADS
1831 attr = GetFileAttributesA(path);
1832 if (attr != 0xFFFFFFFF) {
1833 if (i & _S_IWRITE)
1834 attr &= ~FILE_ATTRIBUTE_READONLY;
1835 else
1836 attr |= FILE_ATTRIBUTE_READONLY;
1837 res = SetFileAttributesA(path, attr);
1838 }
1839 else
1840 res = 0;
1841 Py_END_ALLOW_THREADS
1842 if (!res) {
1843 win32_error("chmod", path);
1844 PyMem_Free(path);
1845 return NULL;
1846 }
1847 PyMem_Free(path);
1848 Py_INCREF(Py_None);
1849 return Py_None;
1850#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001851 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001852 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001853 return NULL;
1854 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001855 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001856 Py_END_ALLOW_THREADS
1857 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001858 return posix_error_with_allocated_filename(path);
1859 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001860 Py_INCREF(Py_None);
1861 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001862#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001863}
1864
Christian Heimes4e30a842007-11-30 22:12:06 +00001865#ifdef HAVE_FCHMOD
1866PyDoc_STRVAR(posix_fchmod__doc__,
1867"fchmod(fd, mode)\n\n\
1868Change the access permissions of the file given by file\n\
1869descriptor fd.");
1870
1871static PyObject *
1872posix_fchmod(PyObject *self, PyObject *args)
1873{
1874 int fd, mode, res;
1875 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1876 return NULL;
1877 Py_BEGIN_ALLOW_THREADS
1878 res = fchmod(fd, mode);
1879 Py_END_ALLOW_THREADS
1880 if (res < 0)
1881 return posix_error();
1882 Py_RETURN_NONE;
1883}
1884#endif /* HAVE_FCHMOD */
1885
1886#ifdef HAVE_LCHMOD
1887PyDoc_STRVAR(posix_lchmod__doc__,
1888"lchmod(path, mode)\n\n\
1889Change the access permissions of a file. If path is a symlink, this\n\
1890affects the link itself rather than the target.");
1891
1892static PyObject *
1893posix_lchmod(PyObject *self, PyObject *args)
1894{
1895 char *path = NULL;
1896 int i;
1897 int res;
1898 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1899 &path, &i))
1900 return NULL;
1901 Py_BEGIN_ALLOW_THREADS
1902 res = lchmod(path, i);
1903 Py_END_ALLOW_THREADS
1904 if (res < 0)
1905 return posix_error_with_allocated_filename(path);
1906 PyMem_Free(path);
1907 Py_RETURN_NONE;
1908}
1909#endif /* HAVE_LCHMOD */
1910
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001911
Thomas Wouterscf297e42007-02-23 15:07:44 +00001912#ifdef HAVE_CHFLAGS
1913PyDoc_STRVAR(posix_chflags__doc__,
1914"chflags(path, flags)\n\n\
1915Set file flags.");
1916
1917static PyObject *
1918posix_chflags(PyObject *self, PyObject *args)
1919{
1920 char *path;
1921 unsigned long flags;
1922 int res;
1923 if (!PyArg_ParseTuple(args, "etk:chflags",
1924 Py_FileSystemDefaultEncoding, &path, &flags))
1925 return NULL;
1926 Py_BEGIN_ALLOW_THREADS
1927 res = chflags(path, flags);
1928 Py_END_ALLOW_THREADS
1929 if (res < 0)
1930 return posix_error_with_allocated_filename(path);
1931 PyMem_Free(path);
1932 Py_INCREF(Py_None);
1933 return Py_None;
1934}
1935#endif /* HAVE_CHFLAGS */
1936
1937#ifdef HAVE_LCHFLAGS
1938PyDoc_STRVAR(posix_lchflags__doc__,
1939"lchflags(path, flags)\n\n\
1940Set file flags.\n\
1941This function will not follow symbolic links.");
1942
1943static PyObject *
1944posix_lchflags(PyObject *self, PyObject *args)
1945{
1946 char *path;
1947 unsigned long flags;
1948 int res;
1949 if (!PyArg_ParseTuple(args, "etk:lchflags",
1950 Py_FileSystemDefaultEncoding, &path, &flags))
1951 return NULL;
1952 Py_BEGIN_ALLOW_THREADS
1953 res = lchflags(path, flags);
1954 Py_END_ALLOW_THREADS
1955 if (res < 0)
1956 return posix_error_with_allocated_filename(path);
1957 PyMem_Free(path);
1958 Py_INCREF(Py_None);
1959 return Py_None;
1960}
1961#endif /* HAVE_LCHFLAGS */
1962
Martin v. Löwis244edc82001-10-04 22:44:26 +00001963#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001964PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001965"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001966Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001967
1968static PyObject *
1969posix_chroot(PyObject *self, PyObject *args)
1970{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001971 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001972}
1973#endif
1974
Guido van Rossum21142a01999-01-08 21:05:37 +00001975#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001976PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001977"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001978force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001979
1980static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001981posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001982{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001983 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001984}
1985#endif /* HAVE_FSYNC */
1986
1987#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001988
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001989#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001990extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1991#endif
1992
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001993PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001994"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001995force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001996 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001997
1998static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001999posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002000{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002001 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002002}
2003#endif /* HAVE_FDATASYNC */
2004
2005
Fredrik Lundh10723342000-07-10 16:38:09 +00002006#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002007PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002008"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002009Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002010
Barry Warsaw53699e91996-12-10 23:23:01 +00002011static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002012posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002013{
Mark Hammondef8b6542001-05-13 08:04:26 +00002014 char *path = NULL;
Christian Heimesd5e2b6f2008-03-19 21:50:51 +00002015 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00002016 int res;
Christian Heimesd5e2b6f2008-03-19 21:50:51 +00002017 if (!PyArg_ParseTuple(args, "etll:chown",
Tim Peters5aa91602002-01-30 05:46:57 +00002018 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00002019 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00002020 return NULL;
2021 Py_BEGIN_ALLOW_THREADS
2022 res = chown(path, (uid_t) uid, (gid_t) gid);
2023 Py_END_ALLOW_THREADS
2024 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002025 return posix_error_with_allocated_filename(path);
2026 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00002027 Py_INCREF(Py_None);
2028 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002029}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002030#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002031
Christian Heimes4e30a842007-11-30 22:12:06 +00002032#ifdef HAVE_FCHOWN
2033PyDoc_STRVAR(posix_fchown__doc__,
2034"fchown(fd, uid, gid)\n\n\
2035Change the owner and group id of the file given by file descriptor\n\
2036fd to the numeric uid and gid.");
2037
2038static PyObject *
2039posix_fchown(PyObject *self, PyObject *args)
2040{
2041 int fd, uid, gid;
2042 int res;
2043 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
2044 return NULL;
2045 Py_BEGIN_ALLOW_THREADS
2046 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2047 Py_END_ALLOW_THREADS
2048 if (res < 0)
2049 return posix_error();
2050 Py_RETURN_NONE;
2051}
2052#endif /* HAVE_FCHOWN */
2053
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002054#ifdef HAVE_LCHOWN
2055PyDoc_STRVAR(posix_lchown__doc__,
2056"lchown(path, uid, gid)\n\n\
2057Change the owner and group id of path to the numeric uid and gid.\n\
2058This function will not follow symbolic links.");
2059
2060static PyObject *
2061posix_lchown(PyObject *self, PyObject *args)
2062{
2063 char *path = NULL;
2064 int uid, gid;
2065 int res;
2066 if (!PyArg_ParseTuple(args, "etii:lchown",
2067 Py_FileSystemDefaultEncoding, &path,
2068 &uid, &gid))
2069 return NULL;
2070 Py_BEGIN_ALLOW_THREADS
2071 res = lchown(path, (uid_t) uid, (gid_t) gid);
2072 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00002073 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002074 return posix_error_with_allocated_filename(path);
2075 PyMem_Free(path);
2076 Py_INCREF(Py_None);
2077 return Py_None;
2078}
2079#endif /* HAVE_LCHOWN */
2080
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002081
Guido van Rossum36bc6801995-06-14 22:54:23 +00002082#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002083static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002084posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002085{
2086 char buf[1026];
2087 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002088
2089#ifdef Py_WIN_WIDE_FILENAMES
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002090 if (!use_bytes && unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002091 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00002092 wchar_t *wbuf2 = wbuf;
2093 PyObject *resobj;
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002094 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002095 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002096 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2097 /* If the buffer is large enough, len does not include the
2098 terminating \0. If the buffer is too small, len includes
2099 the space needed for the terminator. */
2100 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2101 wbuf2 = malloc(len * sizeof(wchar_t));
2102 if (wbuf2)
2103 len = GetCurrentDirectoryW(len, wbuf2);
2104 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002105 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002106 if (!wbuf2) {
2107 PyErr_NoMemory();
2108 return NULL;
2109 }
2110 if (!len) {
2111 if (wbuf2 != wbuf) free(wbuf2);
2112 return win32_error("getcwdu", NULL);
2113 }
2114 resobj = PyUnicode_FromWideChar(wbuf2, len);
2115 if (wbuf2 != wbuf) free(wbuf2);
2116 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002117 }
2118#endif
2119
2120 Py_BEGIN_ALLOW_THREADS
2121#if defined(PYOS_OS2) && defined(PYCC_GCC)
2122 res = _getcwd2(buf, sizeof buf);
2123#else
2124 res = getcwd(buf, sizeof buf);
2125#endif
2126 Py_END_ALLOW_THREADS
2127 if (res == NULL)
2128 return posix_error();
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002129 if (use_bytes)
2130 return PyBytes_FromStringAndSize(buf, strlen(buf));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002131 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2132}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002133
2134PyDoc_STRVAR(posix_getcwd__doc__,
2135"getcwd() -> path\n\n\
2136Return a unicode string representing the current working directory.");
2137
2138static PyObject *
2139posix_getcwd_unicode(PyObject *self)
2140{
2141 return posix_getcwd(0);
2142}
2143
2144PyDoc_STRVAR(posix_getcwdb__doc__,
2145"getcwdb() -> path\n\n\
2146Return a bytes string representing the current working directory.");
2147
2148static PyObject *
2149posix_getcwd_bytes(PyObject *self)
2150{
2151 return posix_getcwd(1);
2152}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002153#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002155
Guido van Rossumb6775db1994-08-01 11:34:53 +00002156#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002157PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002158"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002159Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002160
Barry Warsaw53699e91996-12-10 23:23:01 +00002161static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002162posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002163{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002164 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002165}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002166#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002167
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002168
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002169PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002170"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002171Return a list containing the names of the entries in the directory.\n\
2172\n\
2173 path: path of directory to list\n\
2174\n\
2175The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002176entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002177
Barry Warsaw53699e91996-12-10 23:23:01 +00002178static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002179posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002180{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002181 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002182 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002183#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002184
Barry Warsaw53699e91996-12-10 23:23:01 +00002185 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002186 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002187 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002188 WIN32_FIND_DATA FileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002189 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002190 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002191 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002192
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002193#ifdef Py_WIN_WIDE_FILENAMES
2194 /* If on wide-character-capable OS see if argument
2195 is Unicode and if so use wide API. */
2196 if (unicode_file_names()) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002197 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002198 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2199 WIN32_FIND_DATAW wFileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002200 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002201 Py_UNICODE wch;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002202 /* Overallocate for \\*.*\0 */
2203 len = PyUnicode_GET_SIZE(po);
2204 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2205 if (!wnamebuf) {
2206 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002207 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002208 }
2209 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2210 wch = len > 0 ? wnamebuf[len-1] : '\0';
2211 if (wch != L'/' && wch != L'\\' && wch != L':')
2212 wnamebuf[len++] = L'\\';
2213 wcscpy(wnamebuf + len, L"*.*");
2214 if ((d = PyList_New(0)) == NULL) {
2215 free(wnamebuf);
2216 return NULL;
2217 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002218 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2219 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002220 int error = GetLastError();
2221 if (error == ERROR_FILE_NOT_FOUND) {
2222 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002223 return d;
2224 }
2225 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002226 win32_error_unicode("FindFirstFileW", wnamebuf);
2227 free(wnamebuf);
2228 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002229 }
2230 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002231 /* Skip over . and .. */
2232 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2233 wcscmp(wFileData.cFileName, L"..") != 0) {
2234 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2235 if (v == NULL) {
2236 Py_DECREF(d);
2237 d = NULL;
2238 break;
2239 }
2240 if (PyList_Append(d, v) != 0) {
2241 Py_DECREF(v);
2242 Py_DECREF(d);
2243 d = NULL;
2244 break;
2245 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002246 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002247 }
Georg Brandl622927b2006-03-07 12:48:03 +00002248 Py_BEGIN_ALLOW_THREADS
2249 result = FindNextFileW(hFindFile, &wFileData);
2250 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002251 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2252 it got to the end of the directory. */
2253 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2254 Py_DECREF(d);
2255 win32_error_unicode("FindNextFileW", wnamebuf);
2256 FindClose(hFindFile);
2257 free(wnamebuf);
2258 return NULL;
2259 }
Georg Brandl622927b2006-03-07 12:48:03 +00002260 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002261
2262 if (FindClose(hFindFile) == FALSE) {
2263 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002264 win32_error_unicode("FindClose", wnamebuf);
2265 free(wnamebuf);
2266 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002267 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002268 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002269 return d;
2270 }
2271 /* Drop the argument parsing error as narrow strings
2272 are also valid. */
2273 PyErr_Clear();
2274 }
2275#endif
2276
Tim Peters5aa91602002-01-30 05:46:57 +00002277 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002278 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002279 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002280 if (len > 0) {
2281 char ch = namebuf[len-1];
2282 if (ch != SEP && ch != ALTSEP && ch != ':')
2283 namebuf[len++] = '/';
2284 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002285 strcpy(namebuf + len, "*.*");
2286
Barry Warsaw53699e91996-12-10 23:23:01 +00002287 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002288 return NULL;
2289
2290 hFindFile = FindFirstFile(namebuf, &FileData);
2291 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002292 int error = GetLastError();
2293 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002294 return d;
2295 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002296 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002297 }
2298 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002299 /* Skip over . and .. */
2300 if (strcmp(FileData.cFileName, ".") != 0 &&
2301 strcmp(FileData.cFileName, "..") != 0) {
Christian Heimes72b710a2008-05-26 13:28:38 +00002302 v = PyBytes_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002303 if (v == NULL) {
2304 Py_DECREF(d);
2305 d = NULL;
2306 break;
2307 }
2308 if (PyList_Append(d, v) != 0) {
2309 Py_DECREF(v);
2310 Py_DECREF(d);
2311 d = NULL;
2312 break;
2313 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002314 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002315 }
Georg Brandl622927b2006-03-07 12:48:03 +00002316 Py_BEGIN_ALLOW_THREADS
2317 result = FindNextFile(hFindFile, &FileData);
2318 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002319 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2320 it got to the end of the directory. */
2321 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2322 Py_DECREF(d);
2323 win32_error("FindNextFile", namebuf);
2324 FindClose(hFindFile);
2325 return NULL;
2326 }
Georg Brandl622927b2006-03-07 12:48:03 +00002327 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002328
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002329 if (FindClose(hFindFile) == FALSE) {
2330 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002331 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002332 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002333
2334 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002335
Tim Peters0bb44a42000-09-15 07:44:49 +00002336#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002337
2338#ifndef MAX_PATH
2339#define MAX_PATH CCHMAXPATH
2340#endif
2341 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002342 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002343 PyObject *d, *v;
2344 char namebuf[MAX_PATH+5];
2345 HDIR hdir = 1;
2346 ULONG srchcnt = 1;
2347 FILEFINDBUF3 ep;
2348 APIRET rc;
2349
Alexandre Vassalotti70a23712007-10-14 02:05:51 +00002350 if (!PyArg_ParseTuple(args, "et#:listdir",
2351 Py_FileSystemDefaultEncoding, &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002352 return NULL;
2353 if (len >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00002354 PyMem_Free(name);
2355 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002356 return NULL;
2357 }
2358 strcpy(namebuf, name);
2359 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002360 if (*pt == ALTSEP)
2361 *pt = SEP;
2362 if (namebuf[len-1] != SEP)
2363 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002364 strcpy(namebuf + len, "*.*");
2365
Neal Norwitz6c913782007-10-14 03:23:09 +00002366 if ((d = PyList_New(0)) == NULL) {
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002367 PyMem_Free(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002368 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002369 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002370
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002371 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2372 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002373 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002374 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2375 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2376 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002377
2378 if (rc != NO_ERROR) {
2379 errno = ENOENT;
Neal Norwitz6c913782007-10-14 03:23:09 +00002380 return posix_error_with_allocated_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002381 }
2382
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002383 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002384 do {
2385 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002386 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002387 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002388
2389 strcpy(namebuf, ep.achName);
2390
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002391 /* Leave Case of Name Alone -- In Native Form */
2392 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002393
Christian Heimes72b710a2008-05-26 13:28:38 +00002394 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002395 if (v == NULL) {
2396 Py_DECREF(d);
2397 d = NULL;
2398 break;
2399 }
2400 if (PyList_Append(d, v) != 0) {
2401 Py_DECREF(v);
2402 Py_DECREF(d);
2403 d = NULL;
2404 break;
2405 }
2406 Py_DECREF(v);
2407 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2408 }
2409
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002410 PyMem_Free(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002411 return d;
2412#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002413
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002414 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002415 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002416 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002417 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002418 int arg_is_unicode = 1;
2419
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002420 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002421 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2422 arg_is_unicode = 0;
2423 PyErr_Clear();
2424 }
2425 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002426 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002427 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002428 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002429 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002430 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002431 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002432 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002433 return NULL;
2434 }
Georg Brandl622927b2006-03-07 12:48:03 +00002435 for (;;) {
Georg Brandl3dbca812008-07-23 16:10:53 +00002436 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002437 Py_BEGIN_ALLOW_THREADS
2438 ep = readdir(dirp);
2439 Py_END_ALLOW_THREADS
Georg Brandl3dbca812008-07-23 16:10:53 +00002440 if (ep == NULL) {
2441 if (errno == 0) {
2442 break;
2443 } else {
2444 closedir(dirp);
2445 Py_DECREF(d);
2446 return posix_error_with_allocated_filename(name);
2447 }
2448 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002449 if (ep->d_name[0] == '.' &&
2450 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002451 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002452 continue;
Christian Heimes72b710a2008-05-26 13:28:38 +00002453 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002454 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002455 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002456 d = NULL;
2457 break;
2458 }
Just van Rossum96b1c902003-03-03 17:32:15 +00002459 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002460 PyObject *w;
2461
2462 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002463 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002464 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002465 if (w != NULL) {
2466 Py_DECREF(v);
2467 v = w;
2468 }
2469 else {
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002470 /* Ignore undecodable filenames, as discussed
2471 * in issue 3187. To include these,
2472 * use getcwdb(). */
Just van Rossum6a421832003-03-04 19:30:44 +00002473 PyErr_Clear();
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002474 Py_DECREF(v);
2475 continue;
Just van Rossum46c97842003-02-25 21:42:15 +00002476 }
Just van Rossum46c97842003-02-25 21:42:15 +00002477 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002478 if (PyList_Append(d, v) != 0) {
2479 Py_DECREF(v);
2480 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002481 d = NULL;
2482 break;
2483 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002484 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002485 }
2486 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002487 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002488
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002489 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002490
Tim Peters0bb44a42000-09-15 07:44:49 +00002491#endif /* which OS */
2492} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002493
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002494#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002495/* A helper function for abspath on win32 */
2496static PyObject *
2497posix__getfullpathname(PyObject *self, PyObject *args)
2498{
Mark Dickinson934896d2009-02-21 20:59:32 +00002499 /* assume encoded strings won't more than double no of chars */
Mark Hammondef8b6542001-05-13 08:04:26 +00002500 char inbuf[MAX_PATH*2];
2501 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002502 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002503 char outbuf[MAX_PATH*2];
2504 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002505#ifdef Py_WIN_WIDE_FILENAMES
2506 if (unicode_file_names()) {
2507 PyUnicodeObject *po;
2508 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
Benjamin Petersonf608c612008-11-16 18:33:53 +00002509 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2510 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002511 Py_UNICODE *wtemp;
Benjamin Petersonf608c612008-11-16 18:33:53 +00002512 DWORD result;
2513 PyObject *v;
2514 result = GetFullPathNameW(wpath,
2515 sizeof(woutbuf)/sizeof(woutbuf[0]),
2516 woutbuf, &wtemp);
2517 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2518 woutbufp = malloc(result * sizeof(Py_UNICODE));
2519 if (!woutbufp)
2520 return PyErr_NoMemory();
2521 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2522 }
2523 if (result)
2524 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2525 else
2526 v = win32_error_unicode("GetFullPathNameW", wpath);
2527 if (woutbufp != woutbuf)
2528 free(woutbufp);
2529 return v;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002530 }
2531 /* Drop the argument parsing error as narrow strings
2532 are also valid. */
2533 PyErr_Clear();
2534 }
2535#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002536 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2537 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002538 &insize))
2539 return NULL;
2540 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2541 outbuf, &temp))
2542 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002543 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2544 return PyUnicode_Decode(outbuf, strlen(outbuf),
2545 Py_FileSystemDefaultEncoding, NULL);
2546 }
Christian Heimes72b710a2008-05-26 13:28:38 +00002547 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002548} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002549#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002550
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002551PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002552"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002553Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002554
Barry Warsaw53699e91996-12-10 23:23:01 +00002555static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002556posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002557{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002558 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002559 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002560 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002561
2562#ifdef Py_WIN_WIDE_FILENAMES
2563 if (unicode_file_names()) {
2564 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002565 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002566 Py_BEGIN_ALLOW_THREADS
2567 /* PyUnicode_AS_UNICODE OK without thread lock as
2568 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002569 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002570 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002571 if (!res)
2572 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002573 Py_INCREF(Py_None);
2574 return Py_None;
2575 }
2576 /* Drop the argument parsing error as narrow strings
2577 are also valid. */
2578 PyErr_Clear();
2579 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002580 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2581 Py_FileSystemDefaultEncoding, &path, &mode))
2582 return NULL;
2583 Py_BEGIN_ALLOW_THREADS
2584 /* PyUnicode_AS_UNICODE OK without thread lock as
2585 it is a simple dereference. */
2586 res = CreateDirectoryA(path, NULL);
2587 Py_END_ALLOW_THREADS
2588 if (!res) {
2589 win32_error("mkdir", path);
2590 PyMem_Free(path);
2591 return NULL;
2592 }
2593 PyMem_Free(path);
2594 Py_INCREF(Py_None);
2595 return Py_None;
2596#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002597
Tim Peters5aa91602002-01-30 05:46:57 +00002598 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002599 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002600 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002601 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002602#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002603 res = mkdir(path);
2604#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002605 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002606#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002607 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002608 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002609 return posix_error_with_allocated_filename(path);
2610 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002611 Py_INCREF(Py_None);
2612 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002613#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002614}
2615
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002616
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002617/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2618#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002619#include <sys/resource.h>
2620#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002621
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002622
2623#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002624PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002625"nice(inc) -> new_priority\n\n\
2626Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002627
Barry Warsaw53699e91996-12-10 23:23:01 +00002628static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002629posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002630{
2631 int increment, value;
2632
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002633 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002634 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002635
2636 /* There are two flavours of 'nice': one that returns the new
2637 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002638 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2639 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002640
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002641 If we are of the nice family that returns the new priority, we
2642 need to clear errno before the call, and check if errno is filled
2643 before calling posix_error() on a returnvalue of -1, because the
2644 -1 may be the actual new priority! */
2645
2646 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002647 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002648#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002649 if (value == 0)
2650 value = getpriority(PRIO_PROCESS, 0);
2651#endif
2652 if (value == -1 && errno != 0)
2653 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002654 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00002655 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002656}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002657#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002658
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002659PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002660"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002661Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002662
Barry Warsaw53699e91996-12-10 23:23:01 +00002663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002664posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002665{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002666#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002667 PyObject *o1, *o2;
2668 char *p1, *p2;
2669 BOOL result;
2670 if (unicode_file_names()) {
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002671 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2672 goto error;
2673 if (!convert_to_unicode(&o1))
2674 goto error;
2675 if (!convert_to_unicode(&o2)) {
2676 Py_DECREF(o1);
2677 goto error;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002678 }
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002679 Py_BEGIN_ALLOW_THREADS
2680 result = MoveFileW(PyUnicode_AsUnicode(o1),
2681 PyUnicode_AsUnicode(o2));
2682 Py_END_ALLOW_THREADS
2683 Py_DECREF(o1);
2684 Py_DECREF(o2);
2685 if (!result)
2686 return win32_error("rename", NULL);
2687 Py_INCREF(Py_None);
2688 return Py_None;
2689error:
2690 PyErr_Clear();
Thomas Wouters477c8d52006-05-27 19:21:47 +00002691 }
2692 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2693 return NULL;
2694 Py_BEGIN_ALLOW_THREADS
2695 result = MoveFileA(p1, p2);
2696 Py_END_ALLOW_THREADS
2697 if (!result)
2698 return win32_error("rename", NULL);
2699 Py_INCREF(Py_None);
2700 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002701#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002702 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002703#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002704}
2705
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002706
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002707PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002708"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002709Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002710
Barry Warsaw53699e91996-12-10 23:23:01 +00002711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002712posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002713{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002714#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00002715 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002716#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002717 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002718#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002719}
2720
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002721
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002722PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002723"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002724Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002725
Barry Warsaw53699e91996-12-10 23:23:01 +00002726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002727posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002728{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002729#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002730 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002731#else
2732 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2733#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002734}
2735
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002736
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002737#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002738PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002739"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002740Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002741
Barry Warsaw53699e91996-12-10 23:23:01 +00002742static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002743posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002744{
Guido van Rossumff4949e1992-08-05 19:58:53 +00002745 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002746#ifdef MS_WINDOWS
2747 wchar_t *command;
2748 if (!PyArg_ParseTuple(args, "u:system", &command))
2749 return NULL;
2750#else
2751 char *command;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002752 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002753 return NULL;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002754#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002755 Py_BEGIN_ALLOW_THREADS
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002756#ifdef MS_WINDOWS
2757 sts = _wsystem(command);
2758#else
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002759 sts = system(command);
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002760#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002761 Py_END_ALLOW_THREADS
Christian Heimes217cfd12007-12-02 14:31:20 +00002762 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002763}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002764#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002765
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002766
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002767PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002768"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002769Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002770
Barry Warsaw53699e91996-12-10 23:23:01 +00002771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002772posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002773{
2774 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002775 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002776 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002777 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002778 if (i < 0)
2779 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00002780 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002781}
2782
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002783
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002784PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002785"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002786Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002787
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002788PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002789"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002790Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002791
Barry Warsaw53699e91996-12-10 23:23:01 +00002792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002793posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002794{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002795#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00002796 return win32_1str(args, "remove", "y:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002797#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002798 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002799#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002800}
2801
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002802
Guido van Rossumb6775db1994-08-01 11:34:53 +00002803#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002804PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002805"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002806Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002807
Barry Warsaw53699e91996-12-10 23:23:01 +00002808static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002809posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002810{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002811 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002812 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002813
Barry Warsaw53699e91996-12-10 23:23:01 +00002814 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002815 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002816 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002817 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002818 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002819 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002820 u.sysname,
2821 u.nodename,
2822 u.release,
2823 u.version,
2824 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002825}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002826#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002827
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002828static int
2829extract_time(PyObject *t, long* sec, long* usec)
2830{
2831 long intval;
2832 if (PyFloat_Check(t)) {
2833 double tval = PyFloat_AsDouble(t);
Christian Heimes90aa7642007-12-19 02:45:37 +00002834 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002835 if (!intobj)
2836 return -1;
Christian Heimes217cfd12007-12-02 14:31:20 +00002837 intval = PyLong_AsLong(intobj);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002838 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002839 if (intval == -1 && PyErr_Occurred())
2840 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002841 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002842 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002843 if (*usec < 0)
2844 /* If rounding gave us a negative number,
2845 truncate. */
2846 *usec = 0;
2847 return 0;
2848 }
Christian Heimes217cfd12007-12-02 14:31:20 +00002849 intval = PyLong_AsLong(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002850 if (intval == -1 && PyErr_Occurred())
2851 return -1;
2852 *sec = intval;
2853 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002854 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002855}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002856
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002857PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002858"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002859utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002860Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002861second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002862
Barry Warsaw53699e91996-12-10 23:23:01 +00002863static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002864posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002865{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002866#ifdef Py_WIN_WIDE_FILENAMES
2867 PyObject *arg;
2868 PyUnicodeObject *obwpath;
2869 wchar_t *wpath = NULL;
2870 char *apath = NULL;
2871 HANDLE hFile;
2872 long atimesec, mtimesec, ausec, musec;
2873 FILETIME atime, mtime;
2874 PyObject *result = NULL;
2875
2876 if (unicode_file_names()) {
2877 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2878 wpath = PyUnicode_AS_UNICODE(obwpath);
2879 Py_BEGIN_ALLOW_THREADS
2880 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002881 NULL, OPEN_EXISTING,
2882 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002883 Py_END_ALLOW_THREADS
2884 if (hFile == INVALID_HANDLE_VALUE)
2885 return win32_error_unicode("utime", wpath);
2886 } else
2887 /* Drop the argument parsing error as narrow strings
2888 are also valid. */
2889 PyErr_Clear();
2890 }
2891 if (!wpath) {
2892 if (!PyArg_ParseTuple(args, "etO:utime",
2893 Py_FileSystemDefaultEncoding, &apath, &arg))
2894 return NULL;
2895 Py_BEGIN_ALLOW_THREADS
2896 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002897 NULL, OPEN_EXISTING,
2898 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002899 Py_END_ALLOW_THREADS
2900 if (hFile == INVALID_HANDLE_VALUE) {
2901 win32_error("utime", apath);
2902 PyMem_Free(apath);
2903 return NULL;
2904 }
2905 PyMem_Free(apath);
2906 }
2907
2908 if (arg == Py_None) {
2909 SYSTEMTIME now;
2910 GetSystemTime(&now);
2911 if (!SystemTimeToFileTime(&now, &mtime) ||
2912 !SystemTimeToFileTime(&now, &atime)) {
2913 win32_error("utime", NULL);
2914 goto done;
2915 }
2916 }
2917 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2918 PyErr_SetString(PyExc_TypeError,
2919 "utime() arg 2 must be a tuple (atime, mtime)");
2920 goto done;
2921 }
2922 else {
2923 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2924 &atimesec, &ausec) == -1)
2925 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002926 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002927 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2928 &mtimesec, &musec) == -1)
2929 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002930 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002931 }
2932 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2933 /* Avoid putting the file name into the error here,
2934 as that may confuse the user into believing that
2935 something is wrong with the file, when it also
2936 could be the time stamp that gives a problem. */
2937 win32_error("utime", NULL);
2938 }
2939 Py_INCREF(Py_None);
2940 result = Py_None;
2941done:
2942 CloseHandle(hFile);
2943 return result;
2944#else /* Py_WIN_WIDE_FILENAMES */
2945
Neal Norwitz2adf2102004-06-09 01:46:02 +00002946 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002947 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002948 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002949 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002950
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002951#if defined(HAVE_UTIMES)
2952 struct timeval buf[2];
2953#define ATIME buf[0].tv_sec
2954#define MTIME buf[1].tv_sec
2955#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002956/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002957 struct utimbuf buf;
2958#define ATIME buf.actime
2959#define MTIME buf.modtime
2960#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002961#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002962 time_t buf[2];
2963#define ATIME buf[0]
2964#define MTIME buf[1]
2965#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002966#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002967
Mark Hammond817c9292003-12-03 01:22:38 +00002968
Thomas Wouters477c8d52006-05-27 19:21:47 +00002969 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002970 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002971 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002972 if (arg == Py_None) {
2973 /* optional time values not given */
2974 Py_BEGIN_ALLOW_THREADS
2975 res = utime(path, NULL);
2976 Py_END_ALLOW_THREADS
2977 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002978 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002979 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002980 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002981 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002982 return NULL;
2983 }
2984 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002985 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002986 &atime, &ausec) == -1) {
2987 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002988 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002989 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002990 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002991 &mtime, &musec) == -1) {
2992 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002993 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002994 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002995 ATIME = atime;
2996 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002997#ifdef HAVE_UTIMES
2998 buf[0].tv_usec = ausec;
2999 buf[1].tv_usec = musec;
3000 Py_BEGIN_ALLOW_THREADS
3001 res = utimes(path, buf);
3002 Py_END_ALLOW_THREADS
3003#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00003004 Py_BEGIN_ALLOW_THREADS
3005 res = utime(path, UTIME_ARG);
3006 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003007#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00003008 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00003009 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00003010 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00003011 }
Neal Norwitz96652712004-06-06 20:40:27 +00003012 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003013 Py_INCREF(Py_None);
3014 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003015#undef UTIME_ARG
3016#undef ATIME
3017#undef MTIME
Thomas Wouters477c8d52006-05-27 19:21:47 +00003018#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003019}
3020
Guido van Rossum85e3b011991-06-03 12:42:10 +00003021
Guido van Rossum3b066191991-06-04 19:40:25 +00003022/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003023
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003024PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003025"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003026Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003027
Barry Warsaw53699e91996-12-10 23:23:01 +00003028static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003029posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003030{
3031 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003032 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003033 return NULL;
3034 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00003035 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003036}
3037
Martin v. Löwis114619e2002-10-07 06:44:21 +00003038#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3039static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003040free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003041{
Martin v. Löwis725507b2006-03-07 12:08:51 +00003042 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00003043 for (i = 0; i < count; i++)
3044 PyMem_Free(array[i]);
3045 PyMem_DEL(array);
3046}
3047#endif
3048
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003049
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003050#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003051PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003052"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003053Execute an executable path with arguments, replacing current process.\n\
3054\n\
3055 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003056 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003057
Barry Warsaw53699e91996-12-10 23:23:01 +00003058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003059posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003060{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003061 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003062 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003063 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003064 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003065 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003066
Guido van Rossum89b33251993-10-22 14:26:06 +00003067 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00003068 argv is a list or tuple of strings. */
3069
Martin v. Löwis114619e2002-10-07 06:44:21 +00003070 if (!PyArg_ParseTuple(args, "etO:execv",
3071 Py_FileSystemDefaultEncoding,
3072 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003073 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003074 if (PyList_Check(argv)) {
3075 argc = PyList_Size(argv);
3076 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003077 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003078 else if (PyTuple_Check(argv)) {
3079 argc = PyTuple_Size(argv);
3080 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003081 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003082 else {
Fred Drake661ea262000-10-24 19:57:45 +00003083 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003084 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00003085 return NULL;
3086 }
Thomas Heller6790d602007-08-30 17:15:14 +00003087 if (argc < 1) {
3088 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3089 PyMem_Free(path);
3090 return NULL;
3091 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003092
Barry Warsaw53699e91996-12-10 23:23:01 +00003093 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003094 if (argvlist == NULL) {
3095 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003096 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003097 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003098 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003099 if (!PyArg_Parse((*getitem)(argv, i), "et",
3100 Py_FileSystemDefaultEncoding,
3101 &argvlist[i])) {
3102 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00003103 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00003104 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003105 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00003106 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003107
Guido van Rossum85e3b011991-06-03 12:42:10 +00003108 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003109 }
3110 argvlist[argc] = NULL;
3111
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003112 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003113
Guido van Rossum85e3b011991-06-03 12:42:10 +00003114 /* If we get here it's definitely an error */
3115
Martin v. Löwis114619e2002-10-07 06:44:21 +00003116 free_string_array(argvlist, argc);
3117 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003118 return posix_error();
3119}
3120
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003121
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003122PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003123"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003124Execute a path with arguments and environment, replacing current process.\n\
3125\n\
3126 path: path of executable file\n\
3127 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003128 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003129
Barry Warsaw53699e91996-12-10 23:23:01 +00003130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003131posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003132{
3133 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003134 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003135 char **argvlist;
3136 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003137 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003138 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003139 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003140 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003141
3142 /* execve has three arguments: (path, argv, env), where
3143 argv is a list or tuple of strings and env is a dictionary
3144 like posix.environ. */
3145
Martin v. Löwis114619e2002-10-07 06:44:21 +00003146 if (!PyArg_ParseTuple(args, "etOO:execve",
3147 Py_FileSystemDefaultEncoding,
3148 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003149 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003150 if (PyList_Check(argv)) {
3151 argc = PyList_Size(argv);
3152 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003153 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003154 else if (PyTuple_Check(argv)) {
3155 argc = PyTuple_Size(argv);
3156 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003157 }
3158 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003159 PyErr_SetString(PyExc_TypeError,
3160 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003161 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003162 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003163 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003164 PyErr_SetString(PyExc_TypeError,
3165 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003166 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003167 }
3168
Barry Warsaw53699e91996-12-10 23:23:01 +00003169 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003170 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003171 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003172 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003173 }
3174 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003175 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003176 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003177 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003178 &argvlist[i]))
3179 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003180 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003181 goto fail_1;
3182 }
3183 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003184 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003185 argvlist[argc] = NULL;
3186
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003187 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003188 if (i < 0)
3189 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003190 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003191 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003192 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003193 goto fail_1;
3194 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003195 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003196 keys = PyMapping_Keys(env);
3197 vals = PyMapping_Values(env);
3198 if (!keys || !vals)
3199 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003200 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3201 PyErr_SetString(PyExc_TypeError,
3202 "execve(): env.keys() or env.values() is not a list");
3203 goto fail_2;
3204 }
Tim Peters5aa91602002-01-30 05:46:57 +00003205
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003206 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003207 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003208 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003209
3210 key = PyList_GetItem(keys, pos);
3211 val = PyList_GetItem(vals, pos);
3212 if (!key || !val)
3213 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003214
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003215 if (!PyArg_Parse(
3216 key,
3217 "s;execve() arg 3 contains a non-string key",
3218 &k) ||
3219 !PyArg_Parse(
3220 val,
3221 "s;execve() arg 3 contains a non-string value",
3222 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003223 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003224 goto fail_2;
3225 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003226
3227#if defined(PYOS_OS2)
3228 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3229 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3230#endif
Christian Heimes830a4bc2007-11-22 07:43:40 +00003231 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003232 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003233 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003234 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003235 goto fail_2;
3236 }
Tim Petersc8996f52001-12-03 20:41:00 +00003237 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003238 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003239#if defined(PYOS_OS2)
3240 }
3241#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003242 }
3243 envlist[envc] = 0;
3244
3245 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003246
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003247 /* If we get here it's definitely an error */
3248
3249 (void) posix_error();
3250
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003251 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003252 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003253 PyMem_DEL(envlist[envc]);
3254 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003255 fail_1:
3256 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003257 Py_XDECREF(vals);
3258 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003259 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003260 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003261 return NULL;
3262}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003263#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003264
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003265
Guido van Rossuma1065681999-01-25 23:20:23 +00003266#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003267PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003268"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003269Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003270\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003271 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003272 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003273 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003274
3275static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003276posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003277{
3278 char *path;
3279 PyObject *argv;
3280 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003281 int mode, i;
3282 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003283 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003284 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003285
3286 /* spawnv has three arguments: (mode, path, argv), where
3287 argv is a list or tuple of strings. */
3288
Martin v. Löwis114619e2002-10-07 06:44:21 +00003289 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3290 Py_FileSystemDefaultEncoding,
3291 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003292 return NULL;
3293 if (PyList_Check(argv)) {
3294 argc = PyList_Size(argv);
3295 getitem = PyList_GetItem;
3296 }
3297 else if (PyTuple_Check(argv)) {
3298 argc = PyTuple_Size(argv);
3299 getitem = PyTuple_GetItem;
3300 }
3301 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003302 PyErr_SetString(PyExc_TypeError,
3303 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003304 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003305 return NULL;
3306 }
3307
3308 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003309 if (argvlist == NULL) {
3310 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003311 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003312 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003313 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003314 if (!PyArg_Parse((*getitem)(argv, i), "et",
3315 Py_FileSystemDefaultEncoding,
3316 &argvlist[i])) {
3317 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003318 PyErr_SetString(
3319 PyExc_TypeError,
3320 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003321 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003322 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003323 }
3324 }
3325 argvlist[argc] = NULL;
3326
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003327#if defined(PYOS_OS2) && defined(PYCC_GCC)
3328 Py_BEGIN_ALLOW_THREADS
3329 spawnval = spawnv(mode, path, argvlist);
3330 Py_END_ALLOW_THREADS
3331#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003332 if (mode == _OLD_P_OVERLAY)
3333 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003334
Tim Peters25059d32001-12-07 20:35:43 +00003335 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003336 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003337 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003338#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003339
Martin v. Löwis114619e2002-10-07 06:44:21 +00003340 free_string_array(argvlist, argc);
3341 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003342
Fred Drake699f3522000-06-29 21:12:41 +00003343 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003344 return posix_error();
3345 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003346#if SIZEOF_LONG == SIZEOF_VOID_P
3347 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003348#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003349 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003350#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003351}
3352
3353
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003354PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003355"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003356Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003357\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003358 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003359 path: path of executable file\n\
3360 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003361 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003362
3363static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003364posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003365{
3366 char *path;
3367 PyObject *argv, *env;
3368 char **argvlist;
3369 char **envlist;
3370 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003371 int mode, pos, envc;
3372 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003373 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003374 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003375 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003376
3377 /* spawnve has four arguments: (mode, path, argv, env), where
3378 argv is a list or tuple of strings and env is a dictionary
3379 like posix.environ. */
3380
Martin v. Löwis114619e2002-10-07 06:44:21 +00003381 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3382 Py_FileSystemDefaultEncoding,
3383 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003384 return NULL;
3385 if (PyList_Check(argv)) {
3386 argc = PyList_Size(argv);
3387 getitem = PyList_GetItem;
3388 }
3389 else if (PyTuple_Check(argv)) {
3390 argc = PyTuple_Size(argv);
3391 getitem = PyTuple_GetItem;
3392 }
3393 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003394 PyErr_SetString(PyExc_TypeError,
3395 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003396 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003397 }
3398 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003399 PyErr_SetString(PyExc_TypeError,
3400 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003401 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003402 }
3403
3404 argvlist = PyMem_NEW(char *, argc+1);
3405 if (argvlist == NULL) {
3406 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003407 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003408 }
3409 for (i = 0; i < argc; i++) {
3410 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003411 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003412 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003413 &argvlist[i]))
3414 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003415 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003416 goto fail_1;
3417 }
3418 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003419 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003420 argvlist[argc] = NULL;
3421
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003422 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003423 if (i < 0)
3424 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003425 envlist = PyMem_NEW(char *, i + 1);
3426 if (envlist == NULL) {
3427 PyErr_NoMemory();
3428 goto fail_1;
3429 }
3430 envc = 0;
3431 keys = PyMapping_Keys(env);
3432 vals = PyMapping_Values(env);
3433 if (!keys || !vals)
3434 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003435 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3436 PyErr_SetString(PyExc_TypeError,
3437 "spawnve(): env.keys() or env.values() is not a list");
3438 goto fail_2;
3439 }
Tim Peters5aa91602002-01-30 05:46:57 +00003440
Guido van Rossuma1065681999-01-25 23:20:23 +00003441 for (pos = 0; pos < i; pos++) {
3442 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003443 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003444
3445 key = PyList_GetItem(keys, pos);
3446 val = PyList_GetItem(vals, pos);
3447 if (!key || !val)
3448 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003449
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003450 if (!PyArg_Parse(
3451 key,
3452 "s;spawnve() arg 3 contains a non-string key",
3453 &k) ||
3454 !PyArg_Parse(
3455 val,
3456 "s;spawnve() arg 3 contains a non-string value",
3457 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003458 {
3459 goto fail_2;
3460 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003461 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003462 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003463 if (p == NULL) {
3464 PyErr_NoMemory();
3465 goto fail_2;
3466 }
Tim Petersc8996f52001-12-03 20:41:00 +00003467 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003468 envlist[envc++] = p;
3469 }
3470 envlist[envc] = 0;
3471
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003472#if defined(PYOS_OS2) && defined(PYCC_GCC)
3473 Py_BEGIN_ALLOW_THREADS
3474 spawnval = spawnve(mode, path, argvlist, envlist);
3475 Py_END_ALLOW_THREADS
3476#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003477 if (mode == _OLD_P_OVERLAY)
3478 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003479
3480 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003481 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003482 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003483#endif
Tim Peters25059d32001-12-07 20:35:43 +00003484
Fred Drake699f3522000-06-29 21:12:41 +00003485 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003486 (void) posix_error();
3487 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003488#if SIZEOF_LONG == SIZEOF_VOID_P
3489 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003490#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003491 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003492#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003493
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003494 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003495 while (--envc >= 0)
3496 PyMem_DEL(envlist[envc]);
3497 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003498 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003499 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003500 Py_XDECREF(vals);
3501 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003502 fail_0:
3503 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003504 return res;
3505}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003506
3507/* OS/2 supports spawnvp & spawnvpe natively */
3508#if defined(PYOS_OS2)
3509PyDoc_STRVAR(posix_spawnvp__doc__,
3510"spawnvp(mode, file, args)\n\n\
3511Execute the program 'file' in a new process, using the environment\n\
3512search path to find the file.\n\
3513\n\
3514 mode: mode of process creation\n\
3515 file: executable file name\n\
3516 args: tuple or list of strings");
3517
3518static PyObject *
3519posix_spawnvp(PyObject *self, PyObject *args)
3520{
3521 char *path;
3522 PyObject *argv;
3523 char **argvlist;
3524 int mode, i, argc;
3525 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003526 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003527
3528 /* spawnvp has three arguments: (mode, path, argv), where
3529 argv is a list or tuple of strings. */
3530
3531 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3532 Py_FileSystemDefaultEncoding,
3533 &path, &argv))
3534 return NULL;
3535 if (PyList_Check(argv)) {
3536 argc = PyList_Size(argv);
3537 getitem = PyList_GetItem;
3538 }
3539 else if (PyTuple_Check(argv)) {
3540 argc = PyTuple_Size(argv);
3541 getitem = PyTuple_GetItem;
3542 }
3543 else {
3544 PyErr_SetString(PyExc_TypeError,
3545 "spawnvp() arg 2 must be a tuple or list");
3546 PyMem_Free(path);
3547 return NULL;
3548 }
3549
3550 argvlist = PyMem_NEW(char *, argc+1);
3551 if (argvlist == NULL) {
3552 PyMem_Free(path);
3553 return PyErr_NoMemory();
3554 }
3555 for (i = 0; i < argc; i++) {
3556 if (!PyArg_Parse((*getitem)(argv, i), "et",
3557 Py_FileSystemDefaultEncoding,
3558 &argvlist[i])) {
3559 free_string_array(argvlist, i);
3560 PyErr_SetString(
3561 PyExc_TypeError,
3562 "spawnvp() arg 2 must contain only strings");
3563 PyMem_Free(path);
3564 return NULL;
3565 }
3566 }
3567 argvlist[argc] = NULL;
3568
3569 Py_BEGIN_ALLOW_THREADS
3570#if defined(PYCC_GCC)
3571 spawnval = spawnvp(mode, path, argvlist);
3572#else
3573 spawnval = _spawnvp(mode, path, argvlist);
3574#endif
3575 Py_END_ALLOW_THREADS
3576
3577 free_string_array(argvlist, argc);
3578 PyMem_Free(path);
3579
3580 if (spawnval == -1)
3581 return posix_error();
3582 else
3583 return Py_BuildValue("l", (long) spawnval);
3584}
3585
3586
3587PyDoc_STRVAR(posix_spawnvpe__doc__,
3588"spawnvpe(mode, file, args, env)\n\n\
3589Execute the program 'file' in a new process, using the environment\n\
3590search path to find the file.\n\
3591\n\
3592 mode: mode of process creation\n\
3593 file: executable file name\n\
3594 args: tuple or list of arguments\n\
3595 env: dictionary of strings mapping to strings");
3596
3597static PyObject *
3598posix_spawnvpe(PyObject *self, PyObject *args)
3599{
3600 char *path;
3601 PyObject *argv, *env;
3602 char **argvlist;
3603 char **envlist;
3604 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3605 int mode, i, pos, argc, envc;
3606 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003607 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003608 int lastarg = 0;
3609
3610 /* spawnvpe has four arguments: (mode, path, argv, env), where
3611 argv is a list or tuple of strings and env is a dictionary
3612 like posix.environ. */
3613
3614 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3615 Py_FileSystemDefaultEncoding,
3616 &path, &argv, &env))
3617 return NULL;
3618 if (PyList_Check(argv)) {
3619 argc = PyList_Size(argv);
3620 getitem = PyList_GetItem;
3621 }
3622 else if (PyTuple_Check(argv)) {
3623 argc = PyTuple_Size(argv);
3624 getitem = PyTuple_GetItem;
3625 }
3626 else {
3627 PyErr_SetString(PyExc_TypeError,
3628 "spawnvpe() arg 2 must be a tuple or list");
3629 goto fail_0;
3630 }
3631 if (!PyMapping_Check(env)) {
3632 PyErr_SetString(PyExc_TypeError,
3633 "spawnvpe() arg 3 must be a mapping object");
3634 goto fail_0;
3635 }
3636
3637 argvlist = PyMem_NEW(char *, argc+1);
3638 if (argvlist == NULL) {
3639 PyErr_NoMemory();
3640 goto fail_0;
3641 }
3642 for (i = 0; i < argc; i++) {
3643 if (!PyArg_Parse((*getitem)(argv, i),
3644 "et;spawnvpe() arg 2 must contain only strings",
3645 Py_FileSystemDefaultEncoding,
3646 &argvlist[i]))
3647 {
3648 lastarg = i;
3649 goto fail_1;
3650 }
3651 }
3652 lastarg = argc;
3653 argvlist[argc] = NULL;
3654
3655 i = PyMapping_Size(env);
3656 if (i < 0)
3657 goto fail_1;
3658 envlist = PyMem_NEW(char *, i + 1);
3659 if (envlist == NULL) {
3660 PyErr_NoMemory();
3661 goto fail_1;
3662 }
3663 envc = 0;
3664 keys = PyMapping_Keys(env);
3665 vals = PyMapping_Values(env);
3666 if (!keys || !vals)
3667 goto fail_2;
3668 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3669 PyErr_SetString(PyExc_TypeError,
3670 "spawnvpe(): env.keys() or env.values() is not a list");
3671 goto fail_2;
3672 }
3673
3674 for (pos = 0; pos < i; pos++) {
3675 char *p, *k, *v;
3676 size_t len;
3677
3678 key = PyList_GetItem(keys, pos);
3679 val = PyList_GetItem(vals, pos);
3680 if (!key || !val)
3681 goto fail_2;
3682
3683 if (!PyArg_Parse(
3684 key,
3685 "s;spawnvpe() arg 3 contains a non-string key",
3686 &k) ||
3687 !PyArg_Parse(
3688 val,
3689 "s;spawnvpe() arg 3 contains a non-string value",
3690 &v))
3691 {
3692 goto fail_2;
3693 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003694 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003695 p = PyMem_NEW(char, len);
3696 if (p == NULL) {
3697 PyErr_NoMemory();
3698 goto fail_2;
3699 }
3700 PyOS_snprintf(p, len, "%s=%s", k, v);
3701 envlist[envc++] = p;
3702 }
3703 envlist[envc] = 0;
3704
3705 Py_BEGIN_ALLOW_THREADS
3706#if defined(PYCC_GCC)
Christian Heimes292d3512008-02-03 16:51:08 +00003707 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003708#else
Christian Heimes292d3512008-02-03 16:51:08 +00003709 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003710#endif
3711 Py_END_ALLOW_THREADS
3712
3713 if (spawnval == -1)
3714 (void) posix_error();
3715 else
3716 res = Py_BuildValue("l", (long) spawnval);
3717
3718 fail_2:
3719 while (--envc >= 0)
3720 PyMem_DEL(envlist[envc]);
3721 PyMem_DEL(envlist);
3722 fail_1:
3723 free_string_array(argvlist, lastarg);
3724 Py_XDECREF(vals);
3725 Py_XDECREF(keys);
3726 fail_0:
3727 PyMem_Free(path);
3728 return res;
3729}
3730#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003731#endif /* HAVE_SPAWNV */
3732
3733
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003734#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003735PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003736"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003737Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3738\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003739Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003740
3741static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003742posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003743{
Christian Heimes400adb02008-02-01 08:12:03 +00003744 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003745 if (pid == -1)
3746 return posix_error();
Georg Brandl2ee470f2008-07-16 12:55:28 +00003747 if (pid == 0)
3748 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003749 return PyLong_FromLong(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003750}
3751#endif
3752
3753
Guido van Rossumad0ee831995-03-01 10:34:45 +00003754#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003755PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003756"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003757Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003758Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003759
Barry Warsaw53699e91996-12-10 23:23:01 +00003760static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003761posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003762{
Christian Heimes400adb02008-02-01 08:12:03 +00003763 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003764 if (pid == -1)
3765 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003766 if (pid == 0)
3767 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003768 return PyLong_FromLong(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003769}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003770#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003771
Neal Norwitzb59798b2003-03-21 01:43:31 +00003772/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003773/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3774#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003775#define DEV_PTY_FILE "/dev/ptc"
3776#define HAVE_DEV_PTMX
3777#else
3778#define DEV_PTY_FILE "/dev/ptmx"
3779#endif
3780
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003781#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003782#ifdef HAVE_PTY_H
3783#include <pty.h>
3784#else
3785#ifdef HAVE_LIBUTIL_H
3786#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003787#endif /* HAVE_LIBUTIL_H */
3788#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003789#ifdef HAVE_STROPTS_H
3790#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003791#endif
3792#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003793
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003794#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003795PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003796"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003797Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003798
3799static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003800posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003801{
3802 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003803#ifndef HAVE_OPENPTY
3804 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003805#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003806#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003807 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003808#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003809 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003810#endif
3811#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003812
Thomas Wouters70c21a12000-07-14 14:28:33 +00003813#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003814 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3815 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003816#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003817 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3818 if (slave_name == NULL)
3819 return posix_error();
3820
3821 slave_fd = open(slave_name, O_RDWR);
3822 if (slave_fd < 0)
3823 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003824#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003825 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003826 if (master_fd < 0)
3827 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003828 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003829 /* change permission of slave */
3830 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003831 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003832 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003833 }
3834 /* unlock slave */
3835 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003836 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003837 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003838 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003839 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003840 slave_name = ptsname(master_fd); /* get name of slave */
3841 if (slave_name == NULL)
3842 return posix_error();
3843 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3844 if (slave_fd < 0)
3845 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003846#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003847 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3848 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003849#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003850 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003851#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003852#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003853#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003854
Fred Drake8cef4cf2000-06-28 16:40:38 +00003855 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003856
Fred Drake8cef4cf2000-06-28 16:40:38 +00003857}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003858#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003859
3860#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003861PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003862"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003863Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3864Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003865To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003866
3867static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003868posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003869{
Christian Heimes400adb02008-02-01 08:12:03 +00003870 int master_fd = -1;
3871 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003872
Fred Drake8cef4cf2000-06-28 16:40:38 +00003873 pid = forkpty(&master_fd, NULL, NULL, NULL);
3874 if (pid == -1)
3875 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003876 if (pid == 0)
3877 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003878 return Py_BuildValue("(li)", pid, master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003879}
3880#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003881
Guido van Rossumad0ee831995-03-01 10:34:45 +00003882#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003883PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003884"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003885Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003886
Barry Warsaw53699e91996-12-10 23:23:01 +00003887static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003888posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003889{
Christian Heimes217cfd12007-12-02 14:31:20 +00003890 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003891}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003892#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003893
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003894
Guido van Rossumad0ee831995-03-01 10:34:45 +00003895#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003896PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003897"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003898Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003899
Barry Warsaw53699e91996-12-10 23:23:01 +00003900static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003901posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003902{
Christian Heimes217cfd12007-12-02 14:31:20 +00003903 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003904}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003905#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003906
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003907
Guido van Rossumad0ee831995-03-01 10:34:45 +00003908#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003909PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003910"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003911Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003912
Barry Warsaw53699e91996-12-10 23:23:01 +00003913static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003914posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003915{
Christian Heimes217cfd12007-12-02 14:31:20 +00003916 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003917}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003918#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003919
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003920
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003921PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003922"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003923Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003924
Barry Warsaw53699e91996-12-10 23:23:01 +00003925static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003926posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003927{
Christian Heimes217cfd12007-12-02 14:31:20 +00003928 return PyLong_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003929}
3930
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003931
Fred Drakec9680921999-12-13 16:37:25 +00003932#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003933PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003934"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003935Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003936
3937static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003938posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003939{
3940 PyObject *result = NULL;
3941
Fred Drakec9680921999-12-13 16:37:25 +00003942#ifdef NGROUPS_MAX
3943#define MAX_GROUPS NGROUPS_MAX
3944#else
3945 /* defined to be 16 on Solaris7, so this should be a small number */
3946#define MAX_GROUPS 64
3947#endif
3948 gid_t grouplist[MAX_GROUPS];
3949 int n;
3950
3951 n = getgroups(MAX_GROUPS, grouplist);
3952 if (n < 0)
3953 posix_error();
3954 else {
3955 result = PyList_New(n);
3956 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003957 int i;
3958 for (i = 0; i < n; ++i) {
Christian Heimes217cfd12007-12-02 14:31:20 +00003959 PyObject *o = PyLong_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003960 if (o == NULL) {
3961 Py_DECREF(result);
3962 result = NULL;
3963 break;
3964 }
3965 PyList_SET_ITEM(result, i, o);
3966 }
3967 }
3968 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003969
Fred Drakec9680921999-12-13 16:37:25 +00003970 return result;
3971}
3972#endif
3973
Martin v. Löwis606edc12002-06-13 21:09:11 +00003974#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003975PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003976"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003977Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003978
3979static PyObject *
3980posix_getpgid(PyObject *self, PyObject *args)
3981{
3982 int pid, pgid;
3983 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3984 return NULL;
3985 pgid = getpgid(pid);
3986 if (pgid < 0)
3987 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00003988 return PyLong_FromLong((long)pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00003989}
3990#endif /* HAVE_GETPGID */
3991
3992
Guido van Rossumb6775db1994-08-01 11:34:53 +00003993#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003994PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003995"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003996Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003997
Barry Warsaw53699e91996-12-10 23:23:01 +00003998static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003999posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004000{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004001#ifdef GETPGRP_HAVE_ARG
Christian Heimes217cfd12007-12-02 14:31:20 +00004002 return PyLong_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004003#else /* GETPGRP_HAVE_ARG */
Christian Heimes217cfd12007-12-02 14:31:20 +00004004 return PyLong_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004005#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004006}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004007#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004008
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004009
Guido van Rossumb6775db1994-08-01 11:34:53 +00004010#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004011PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004012"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004013Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004014
Barry Warsaw53699e91996-12-10 23:23:01 +00004015static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004016posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004017{
Guido van Rossum64933891994-10-20 21:56:42 +00004018#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00004019 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004020#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004021 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004022#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00004023 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004024 Py_INCREF(Py_None);
4025 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004026}
4027
Guido van Rossumb6775db1994-08-01 11:34:53 +00004028#endif /* HAVE_SETPGRP */
4029
Guido van Rossumad0ee831995-03-01 10:34:45 +00004030#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004031PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004032"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004033Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004034
Barry Warsaw53699e91996-12-10 23:23:01 +00004035static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004036posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004037{
Christian Heimes217cfd12007-12-02 14:31:20 +00004038 return PyLong_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004039}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004040#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004041
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004042
Fred Drake12c6e2d1999-12-14 21:25:03 +00004043#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004044PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004045"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004046Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004047
4048static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004049posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004050{
Neal Norwitze241ce82003-02-17 18:17:05 +00004051 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00004052 char *name;
4053 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004054
Fred Drakea30680b2000-12-06 21:24:28 +00004055 errno = 0;
4056 name = getlogin();
4057 if (name == NULL) {
4058 if (errno)
4059 posix_error();
4060 else
4061 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00004062 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00004063 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00004064 else
Neal Norwitz93c56822007-08-26 07:10:06 +00004065 result = PyUnicode_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00004066 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004067
Fred Drake12c6e2d1999-12-14 21:25:03 +00004068 return result;
4069}
4070#endif
4071
Guido van Rossumad0ee831995-03-01 10:34:45 +00004072#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004073PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004074"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004075Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004076
Barry Warsaw53699e91996-12-10 23:23:01 +00004077static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004078posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004079{
Christian Heimes217cfd12007-12-02 14:31:20 +00004080 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004081}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004082#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004083
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004084
Guido van Rossumad0ee831995-03-01 10:34:45 +00004085#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004086PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004087"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004088Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004089
Barry Warsaw53699e91996-12-10 23:23:01 +00004090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004091posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004092{
Christian Heimes292d3512008-02-03 16:51:08 +00004093 pid_t pid;
4094 int sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004095 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00004096 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004097#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004098 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4099 APIRET rc;
4100 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004101 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004102
4103 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4104 APIRET rc;
4105 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004106 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004107
4108 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004109 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004110#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00004111 if (kill(pid, sig) == -1)
4112 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004113#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004114 Py_INCREF(Py_None);
4115 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004116}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004117#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004118
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004119#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004120PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004121"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004122Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004123
4124static PyObject *
4125posix_killpg(PyObject *self, PyObject *args)
4126{
4127 int pgid, sig;
4128 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
4129 return NULL;
4130 if (killpg(pgid, sig) == -1)
4131 return posix_error();
4132 Py_INCREF(Py_None);
4133 return Py_None;
4134}
4135#endif
4136
Guido van Rossumc0125471996-06-28 18:55:32 +00004137#ifdef HAVE_PLOCK
4138
4139#ifdef HAVE_SYS_LOCK_H
4140#include <sys/lock.h>
4141#endif
4142
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004143PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004144"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004145Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004146
Barry Warsaw53699e91996-12-10 23:23:01 +00004147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004148posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004149{
4150 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004151 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004152 return NULL;
4153 if (plock(op) == -1)
4154 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004155 Py_INCREF(Py_None);
4156 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004157}
4158#endif
4159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004160
Guido van Rossum3b066191991-06-04 19:40:25 +00004161
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004162
Guido van Rossumb6775db1994-08-01 11:34:53 +00004163#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004164PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004165"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004166Set the current process's user id.");
4167
Barry Warsaw53699e91996-12-10 23:23:01 +00004168static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004169posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004170{
4171 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004172 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004173 return NULL;
4174 if (setuid(uid) < 0)
4175 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004176 Py_INCREF(Py_None);
4177 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004178}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004179#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004180
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004181
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004182#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004183PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004184"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004185Set the current process's effective user id.");
4186
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004187static PyObject *
4188posix_seteuid (PyObject *self, PyObject *args)
4189{
4190 int euid;
4191 if (!PyArg_ParseTuple(args, "i", &euid)) {
4192 return NULL;
4193 } else if (seteuid(euid) < 0) {
4194 return posix_error();
4195 } else {
4196 Py_INCREF(Py_None);
4197 return Py_None;
4198 }
4199}
4200#endif /* HAVE_SETEUID */
4201
4202#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004203PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004204"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004205Set the current process's effective group id.");
4206
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004207static PyObject *
4208posix_setegid (PyObject *self, PyObject *args)
4209{
4210 int egid;
4211 if (!PyArg_ParseTuple(args, "i", &egid)) {
4212 return NULL;
4213 } else if (setegid(egid) < 0) {
4214 return posix_error();
4215 } else {
4216 Py_INCREF(Py_None);
4217 return Py_None;
4218 }
4219}
4220#endif /* HAVE_SETEGID */
4221
4222#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004223PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004224"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004225Set the current process's real and effective user ids.");
4226
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004227static PyObject *
4228posix_setreuid (PyObject *self, PyObject *args)
4229{
4230 int ruid, euid;
4231 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4232 return NULL;
4233 } else if (setreuid(ruid, euid) < 0) {
4234 return posix_error();
4235 } else {
4236 Py_INCREF(Py_None);
4237 return Py_None;
4238 }
4239}
4240#endif /* HAVE_SETREUID */
4241
4242#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004243PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004244"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004245Set the current process's real and effective group ids.");
4246
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004247static PyObject *
4248posix_setregid (PyObject *self, PyObject *args)
4249{
4250 int rgid, egid;
4251 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4252 return NULL;
4253 } else if (setregid(rgid, egid) < 0) {
4254 return posix_error();
4255 } else {
4256 Py_INCREF(Py_None);
4257 return Py_None;
4258 }
4259}
4260#endif /* HAVE_SETREGID */
4261
Guido van Rossumb6775db1994-08-01 11:34:53 +00004262#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004263PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004264"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004265Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004266
Barry Warsaw53699e91996-12-10 23:23:01 +00004267static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004268posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004269{
4270 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004271 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004272 return NULL;
4273 if (setgid(gid) < 0)
4274 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004275 Py_INCREF(Py_None);
4276 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004277}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004278#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004279
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004280#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004281PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004282"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004283Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004284
4285static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004286posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004287{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004288 int i, len;
4289 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004290
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004291 if (!PySequence_Check(groups)) {
4292 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4293 return NULL;
4294 }
4295 len = PySequence_Size(groups);
4296 if (len > MAX_GROUPS) {
4297 PyErr_SetString(PyExc_ValueError, "too many groups");
4298 return NULL;
4299 }
4300 for(i = 0; i < len; i++) {
4301 PyObject *elem;
4302 elem = PySequence_GetItem(groups, i);
4303 if (!elem)
4304 return NULL;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004305 if (!PyLong_Check(elem)) {
4306 PyErr_SetString(PyExc_TypeError,
4307 "groups must be integers");
4308 Py_DECREF(elem);
4309 return NULL;
4310 } else {
4311 unsigned long x = PyLong_AsUnsignedLong(elem);
4312 if (PyErr_Occurred()) {
4313 PyErr_SetString(PyExc_TypeError,
4314 "group id too big");
Georg Brandla13c2442005-11-22 19:30:31 +00004315 Py_DECREF(elem);
4316 return NULL;
Georg Brandla13c2442005-11-22 19:30:31 +00004317 }
Georg Brandla13c2442005-11-22 19:30:31 +00004318 grouplist[i] = x;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004319 /* read back the value to see if it fitted in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00004320 if (grouplist[i] != x) {
4321 PyErr_SetString(PyExc_TypeError,
4322 "group id too big");
4323 Py_DECREF(elem);
4324 return NULL;
4325 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004326 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004327 Py_DECREF(elem);
4328 }
4329
4330 if (setgroups(len, grouplist) < 0)
4331 return posix_error();
4332 Py_INCREF(Py_None);
4333 return Py_None;
4334}
4335#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004336
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004337#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4338static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004339wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004340{
4341 PyObject *result;
4342 static PyObject *struct_rusage;
4343
4344 if (pid == -1)
4345 return posix_error();
4346
4347 if (struct_rusage == NULL) {
Christian Heimes072c0f12008-01-03 23:01:04 +00004348 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004349 if (m == NULL)
4350 return NULL;
4351 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4352 Py_DECREF(m);
4353 if (struct_rusage == NULL)
4354 return NULL;
4355 }
4356
4357 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4358 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4359 if (!result)
4360 return NULL;
4361
4362#ifndef doubletime
4363#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4364#endif
4365
4366 PyStructSequence_SET_ITEM(result, 0,
4367 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4368 PyStructSequence_SET_ITEM(result, 1,
4369 PyFloat_FromDouble(doubletime(ru->ru_stime)));
4370#define SET_INT(result, index, value)\
Christian Heimes217cfd12007-12-02 14:31:20 +00004371 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004372 SET_INT(result, 2, ru->ru_maxrss);
4373 SET_INT(result, 3, ru->ru_ixrss);
4374 SET_INT(result, 4, ru->ru_idrss);
4375 SET_INT(result, 5, ru->ru_isrss);
4376 SET_INT(result, 6, ru->ru_minflt);
4377 SET_INT(result, 7, ru->ru_majflt);
4378 SET_INT(result, 8, ru->ru_nswap);
4379 SET_INT(result, 9, ru->ru_inblock);
4380 SET_INT(result, 10, ru->ru_oublock);
4381 SET_INT(result, 11, ru->ru_msgsnd);
4382 SET_INT(result, 12, ru->ru_msgrcv);
4383 SET_INT(result, 13, ru->ru_nsignals);
4384 SET_INT(result, 14, ru->ru_nvcsw);
4385 SET_INT(result, 15, ru->ru_nivcsw);
4386#undef SET_INT
4387
4388 if (PyErr_Occurred()) {
4389 Py_DECREF(result);
4390 return NULL;
4391 }
4392
4393 return Py_BuildValue("iiN", pid, status, result);
4394}
4395#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4396
4397#ifdef HAVE_WAIT3
4398PyDoc_STRVAR(posix_wait3__doc__,
4399"wait3(options) -> (pid, status, rusage)\n\n\
4400Wait for completion of a child process.");
4401
4402static PyObject *
4403posix_wait3(PyObject *self, PyObject *args)
4404{
Christian Heimes292d3512008-02-03 16:51:08 +00004405 pid_t pid;
4406 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004407 struct rusage ru;
4408 WAIT_TYPE status;
4409 WAIT_STATUS_INT(status) = 0;
4410
4411 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4412 return NULL;
4413
4414 Py_BEGIN_ALLOW_THREADS
4415 pid = wait3(&status, options, &ru);
4416 Py_END_ALLOW_THREADS
4417
4418 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4419}
4420#endif /* HAVE_WAIT3 */
4421
4422#ifdef HAVE_WAIT4
4423PyDoc_STRVAR(posix_wait4__doc__,
4424"wait4(pid, options) -> (pid, status, rusage)\n\n\
4425Wait for completion of a given child process.");
4426
4427static PyObject *
4428posix_wait4(PyObject *self, PyObject *args)
4429{
Christian Heimes292d3512008-02-03 16:51:08 +00004430 pid_t pid;
4431 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004432 struct rusage ru;
4433 WAIT_TYPE status;
4434 WAIT_STATUS_INT(status) = 0;
4435
4436 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
4437 return NULL;
4438
4439 Py_BEGIN_ALLOW_THREADS
4440 pid = wait4(pid, &status, options, &ru);
4441 Py_END_ALLOW_THREADS
4442
4443 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4444}
4445#endif /* HAVE_WAIT4 */
4446
Guido van Rossumb6775db1994-08-01 11:34:53 +00004447#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004448PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004449"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004450Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004451
Barry Warsaw53699e91996-12-10 23:23:01 +00004452static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004453posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004454{
Christian Heimes292d3512008-02-03 16:51:08 +00004455 pid_t pid;
4456 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004457 WAIT_TYPE status;
4458 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004459
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004460 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004461 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004462 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004463 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004464 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004465 if (pid == -1)
4466 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004467
4468 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004469}
4470
Tim Petersab034fa2002-02-01 11:27:43 +00004471#elif defined(HAVE_CWAIT)
4472
4473/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004474PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004475"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004476"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004477
4478static PyObject *
4479posix_waitpid(PyObject *self, PyObject *args)
4480{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004481 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004482 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004483
4484 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4485 return NULL;
4486 Py_BEGIN_ALLOW_THREADS
4487 pid = _cwait(&status, pid, options);
4488 Py_END_ALLOW_THREADS
4489 if (pid == -1)
4490 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004491
4492 /* shift the status left a byte so this is more like the POSIX waitpid */
4493 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004494}
4495#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004496
Guido van Rossumad0ee831995-03-01 10:34:45 +00004497#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004498PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004499"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004500Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004501
Barry Warsaw53699e91996-12-10 23:23:01 +00004502static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004503posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004504{
Christian Heimes292d3512008-02-03 16:51:08 +00004505 pid_t pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004506 WAIT_TYPE status;
4507 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004508
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004509 Py_BEGIN_ALLOW_THREADS
4510 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004511 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004512 if (pid == -1)
4513 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004514
4515 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004516}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004517#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004518
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004519
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004520PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004521"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004522Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004523
Barry Warsaw53699e91996-12-10 23:23:01 +00004524static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004525posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004526{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004527#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004528 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004529#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004530#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00004531 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004532#else
4533 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4534#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004535#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004536}
4537
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004538
Guido van Rossumb6775db1994-08-01 11:34:53 +00004539#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004540PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004541"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004542Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004543
Barry Warsaw53699e91996-12-10 23:23:01 +00004544static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004545posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004546{
Thomas Wouters89f507f2006-12-13 04:49:30 +00004547 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004548 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004549 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004550 int n;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004551 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004552
4553 if (!PyArg_ParseTuple(args, "et:readlink",
4554 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004555 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004556 v = PySequence_GetItem(args, 0);
Neal Norwitzcda5c062007-08-12 17:09:36 +00004557 if (v == NULL) {
4558 PyMem_Free(path);
4559 return NULL;
4560 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004561
4562 if (PyUnicode_Check(v)) {
4563 arg_is_unicode = 1;
4564 }
4565 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004566
Barry Warsaw53699e91996-12-10 23:23:01 +00004567 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004568 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004569 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004570 if (n < 0)
Neal Norwitzfca70052007-08-12 16:56:02 +00004571 return posix_error_with_allocated_filename(path);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004572
Neal Norwitzfca70052007-08-12 16:56:02 +00004573 PyMem_Free(path);
Christian Heimes72b710a2008-05-26 13:28:38 +00004574 v = PyBytes_FromStringAndSize(buf, n);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004575 if (arg_is_unicode) {
4576 PyObject *w;
4577
4578 w = PyUnicode_FromEncodedObject(v,
4579 Py_FileSystemDefaultEncoding,
4580 "strict");
4581 if (w != NULL) {
4582 Py_DECREF(v);
4583 v = w;
4584 }
4585 else {
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004586 v = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004587 }
4588 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004589 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004590}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004591#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004592
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004593
Guido van Rossumb6775db1994-08-01 11:34:53 +00004594#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004595PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004596"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004597Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004598
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004599static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004600posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004601{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004602 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004603}
4604#endif /* HAVE_SYMLINK */
4605
4606
4607#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00004608#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4609static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004610system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004611{
4612 ULONG value = 0;
4613
4614 Py_BEGIN_ALLOW_THREADS
4615 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4616 Py_END_ALLOW_THREADS
4617
4618 return value;
4619}
4620
4621static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004622posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004623{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004624 /* Currently Only Uptime is Provided -- Others Later */
4625 return Py_BuildValue("ddddd",
4626 (double)0 /* t.tms_utime / HZ */,
4627 (double)0 /* t.tms_stime / HZ */,
4628 (double)0 /* t.tms_cutime / HZ */,
4629 (double)0 /* t.tms_cstime / HZ */,
4630 (double)system_uptime() / 1000);
4631}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004632#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00004633#define NEED_TICKS_PER_SECOND
4634static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00004635static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004636posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004637{
4638 struct tms t;
4639 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004640 errno = 0;
4641 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004642 if (c == (clock_t) -1)
4643 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004644 return Py_BuildValue("ddddd",
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00004645 (double)t.tms_utime / ticks_per_second,
4646 (double)t.tms_stime / ticks_per_second,
4647 (double)t.tms_cutime / ticks_per_second,
4648 (double)t.tms_cstime / ticks_per_second,
4649 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004650}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004651#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004652#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004653
4654
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004655#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004656#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004657static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004658posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004659{
4660 FILETIME create, exit, kernel, user;
4661 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004662 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004663 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4664 /* The fields of a FILETIME structure are the hi and lo part
4665 of a 64-bit value expressed in 100 nanosecond units.
4666 1e7 is one second in such units; 1e-7 the inverse.
4667 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4668 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004669 return Py_BuildValue(
4670 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004671 (double)(user.dwHighDateTime*429.4967296 +
4672 user.dwLowDateTime*1e-7),
Christian Heimes68f5fbe2008-02-14 08:27:37 +00004673 (double)(kernel.dwHighDateTime*429.4967296 +
4674 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004675 (double)0,
4676 (double)0,
4677 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004678}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004679#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004680
4681#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004682PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004683"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004684Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004685#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004686
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004687
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004688#ifdef HAVE_GETSID
4689PyDoc_STRVAR(posix_getsid__doc__,
4690"getsid(pid) -> sid\n\n\
4691Call the system call getsid().");
4692
4693static PyObject *
4694posix_getsid(PyObject *self, PyObject *args)
4695{
Christian Heimes292d3512008-02-03 16:51:08 +00004696 pid_t pid;
4697 int sid;
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004698 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
4699 return NULL;
4700 sid = getsid(pid);
4701 if (sid < 0)
4702 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004703 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004704}
4705#endif /* HAVE_GETSID */
4706
4707
Guido van Rossumb6775db1994-08-01 11:34:53 +00004708#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004709PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004710"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004711Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004712
Barry Warsaw53699e91996-12-10 23:23:01 +00004713static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004714posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004715{
Guido van Rossum687dd131993-05-17 08:34:16 +00004716 if (setsid() < 0)
4717 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004718 Py_INCREF(Py_None);
4719 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004720}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004721#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004722
Guido van Rossumb6775db1994-08-01 11:34:53 +00004723#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004724PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004725"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004726Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004727
Barry Warsaw53699e91996-12-10 23:23:01 +00004728static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004729posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004730{
Christian Heimes292d3512008-02-03 16:51:08 +00004731 pid_t pid;
4732 int pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004733 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004734 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004735 if (setpgid(pid, pgrp) < 0)
4736 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004737 Py_INCREF(Py_None);
4738 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004739}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004740#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004741
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004742
Guido van Rossumb6775db1994-08-01 11:34:53 +00004743#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004744PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004745"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004746Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004747
Barry Warsaw53699e91996-12-10 23:23:01 +00004748static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004749posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004750{
Christian Heimes15ebc882008-02-04 18:48:49 +00004751 int fd;
4752 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004753 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004754 return NULL;
4755 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004756 if (pgid < 0)
4757 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004758 return PyLong_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004759}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004760#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004761
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004762
Guido van Rossumb6775db1994-08-01 11:34:53 +00004763#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004764PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004765"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004766Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004767
Barry Warsaw53699e91996-12-10 23:23:01 +00004768static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004769posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004770{
4771 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004772 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004773 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004774 if (tcsetpgrp(fd, pgid) < 0)
4775 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004776 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004777 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004778}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004779#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004780
Guido van Rossum687dd131993-05-17 08:34:16 +00004781/* Functions acting on file descriptors */
4782
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004783PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004784"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004785Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004786
Barry Warsaw53699e91996-12-10 23:23:01 +00004787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004788posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004789{
Mark Hammondef8b6542001-05-13 08:04:26 +00004790 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004791 int flag;
4792 int mode = 0777;
4793 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004794
4795#ifdef MS_WINDOWS
4796 if (unicode_file_names()) {
4797 PyUnicodeObject *po;
4798 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4799 Py_BEGIN_ALLOW_THREADS
4800 /* PyUnicode_AS_UNICODE OK without thread
4801 lock as it is a simple dereference. */
4802 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4803 Py_END_ALLOW_THREADS
4804 if (fd < 0)
4805 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004806 return PyLong_FromLong((long)fd);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004807 }
4808 /* Drop the argument parsing error as narrow strings
4809 are also valid. */
4810 PyErr_Clear();
4811 }
4812#endif
4813
Tim Peters5aa91602002-01-30 05:46:57 +00004814 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004815 Py_FileSystemDefaultEncoding, &file,
4816 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004817 return NULL;
4818
Barry Warsaw53699e91996-12-10 23:23:01 +00004819 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004820 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004821 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004822 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004823 return posix_error_with_allocated_filename(file);
4824 PyMem_Free(file);
Christian Heimes217cfd12007-12-02 14:31:20 +00004825 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004826}
4827
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004828
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004829PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004830"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004831Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004832
Barry Warsaw53699e91996-12-10 23:23:01 +00004833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004834posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004835{
4836 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004837 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004838 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004839 if (!_PyVerify_fd(fd))
4840 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004841 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004842 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004843 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004844 if (res < 0)
4845 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004846 Py_INCREF(Py_None);
4847 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004848}
4849
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004850
Christian Heimesfdab48e2008-01-20 09:06:41 +00004851PyDoc_STRVAR(posix_closerange__doc__,
4852"closerange(fd_low, fd_high)\n\n\
4853Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
4854
4855static PyObject *
4856posix_closerange(PyObject *self, PyObject *args)
4857{
4858 int fd_from, fd_to, i;
4859 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
4860 return NULL;
4861 Py_BEGIN_ALLOW_THREADS
4862 for (i = fd_from; i < fd_to; i++)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004863 if (_PyVerify_fd(i))
4864 close(i);
Christian Heimesfdab48e2008-01-20 09:06:41 +00004865 Py_END_ALLOW_THREADS
4866 Py_RETURN_NONE;
4867}
4868
4869
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004870PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004871"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004872Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004873
Barry Warsaw53699e91996-12-10 23:23:01 +00004874static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004875posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004876{
4877 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004878 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004879 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004880 if (!_PyVerify_fd(fd))
4881 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004882 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004883 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004884 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004885 if (fd < 0)
4886 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004887 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004888}
4889
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004890
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004891PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00004892"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004893Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004894
Barry Warsaw53699e91996-12-10 23:23:01 +00004895static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004896posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004897{
4898 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004899 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004900 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004901 if (!_PyVerify_fd_dup2(fd, fd2))
4902 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004903 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004904 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004905 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004906 if (res < 0)
4907 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004908 Py_INCREF(Py_None);
4909 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004910}
4911
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004912
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004913PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004914"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004915Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004916
Barry Warsaw53699e91996-12-10 23:23:01 +00004917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004918posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004919{
4920 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004921#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00004922 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004923#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004924 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004925#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004926 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004927 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004928 return NULL;
4929#ifdef SEEK_SET
4930 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4931 switch (how) {
4932 case 0: how = SEEK_SET; break;
4933 case 1: how = SEEK_CUR; break;
4934 case 2: how = SEEK_END; break;
4935 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004936#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004937
4938#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00004939 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004940#else
4941 pos = PyLong_Check(posobj) ?
Christian Heimes217cfd12007-12-02 14:31:20 +00004942 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004943#endif
4944 if (PyErr_Occurred())
4945 return NULL;
4946
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004947 if (!_PyVerify_fd(fd))
4948 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004949 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004950#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004951 res = _lseeki64(fd, pos, how);
4952#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004953 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004954#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004955 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004956 if (res < 0)
4957 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004958
4959#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00004960 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004961#else
4962 return PyLong_FromLongLong(res);
4963#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004964}
4965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004966
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004967PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004968"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004969Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004970
Barry Warsaw53699e91996-12-10 23:23:01 +00004971static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004972posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004973{
Guido van Rossum572dbf82007-04-27 23:53:51 +00004974 int fd, size;
4975 Py_ssize_t n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004976 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004977 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004978 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00004979 if (size < 0) {
4980 errno = EINVAL;
4981 return posix_error();
4982 }
Christian Heimes72b710a2008-05-26 13:28:38 +00004983 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004984 if (buffer == NULL)
4985 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004986 if (!_PyVerify_fd(fd))
4987 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004988 Py_BEGIN_ALLOW_THREADS
Christian Heimes72b710a2008-05-26 13:28:38 +00004989 n = read(fd, PyBytes_AS_STRING(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004990 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004991 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004992 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004993 return posix_error();
4994 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004995 if (n != size)
Christian Heimes72b710a2008-05-26 13:28:38 +00004996 _PyBytes_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004997 return buffer;
4998}
4999
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005000
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005001PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005002"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005003Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005004
Barry Warsaw53699e91996-12-10 23:23:01 +00005005static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005006posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005007{
Martin v. Löwis423be952008-08-13 15:53:07 +00005008 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005009 int fd;
5010 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005011
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +00005012 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00005013 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005014 if (!_PyVerify_fd(fd))
5015 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005016 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis423be952008-08-13 15:53:07 +00005017 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00005018 Py_END_ALLOW_THREADS
Martin v. Löwis423be952008-08-13 15:53:07 +00005019 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00005020 if (size < 0)
5021 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00005022 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005023}
5024
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005025
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005026PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005027"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005028Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005029
Barry Warsaw53699e91996-12-10 23:23:01 +00005030static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005031posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005032{
5033 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005034 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005035 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005036 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005037 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005038#ifdef __VMS
5039 /* on OpenVMS we must ensure that all bytes are written to the file */
5040 fsync(fd);
5041#endif
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005042 if (!_PyVerify_fd(fd))
5043 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005044 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005045 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005046 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005047 if (res != 0) {
5048#ifdef MS_WINDOWS
5049 return win32_error("fstat", NULL);
5050#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005051 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005052#endif
5053 }
Tim Peters5aa91602002-01-30 05:46:57 +00005054
Martin v. Löwis14694662006-02-03 12:54:16 +00005055 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005056}
5057
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005058PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005059"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005060Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005061connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005062
5063static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005064posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005065{
5066 int fd;
5067 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5068 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005069 if (!_PyVerify_fd(fd))
5070 return PyBool_FromLong(0);
Fred Drake106c1a02002-04-23 15:58:02 +00005071 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005072}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005073
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005074#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005075PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005076"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005077Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005078
Barry Warsaw53699e91996-12-10 23:23:01 +00005079static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005080posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005081{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005082#if defined(PYOS_OS2)
5083 HFILE read, write;
5084 APIRET rc;
5085
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005086 Py_BEGIN_ALLOW_THREADS
5087 rc = DosCreatePipe( &read, &write, 4096);
5088 Py_END_ALLOW_THREADS
5089 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005090 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005091
5092 return Py_BuildValue("(ii)", read, write);
5093#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005094#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005095 int fds[2];
5096 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005097 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005098 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005099 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005100 if (res != 0)
5101 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005102 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005103#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005104 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005105 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005106 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005107 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005108 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005109 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005110 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005111 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005112 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5113 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005114 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005115#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005116#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005117}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005118#endif /* HAVE_PIPE */
5119
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005120
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005121#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005122PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005123"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005124Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005125
Barry Warsaw53699e91996-12-10 23:23:01 +00005126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005127posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005128{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005129 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005130 int mode = 0666;
5131 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005132 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005133 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005134 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005135 res = mkfifo(filename, mode);
5136 Py_END_ALLOW_THREADS
5137 if (res < 0)
5138 return posix_error();
5139 Py_INCREF(Py_None);
5140 return Py_None;
5141}
5142#endif
5143
5144
Neal Norwitz11690112002-07-30 01:08:28 +00005145#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005146PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005147"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005148Create a filesystem node (file, device special file or named pipe)\n\
5149named filename. mode specifies both the permissions to use and the\n\
5150type of node to be created, being combined (bitwise OR) with one of\n\
5151S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005152device defines the newly created device special file (probably using\n\
5153os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005154
5155
5156static PyObject *
5157posix_mknod(PyObject *self, PyObject *args)
5158{
5159 char *filename;
5160 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005161 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005162 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005163 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005164 return NULL;
5165 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005166 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005167 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005168 if (res < 0)
5169 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005170 Py_INCREF(Py_None);
5171 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005172}
5173#endif
5174
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005175#ifdef HAVE_DEVICE_MACROS
5176PyDoc_STRVAR(posix_major__doc__,
5177"major(device) -> major number\n\
5178Extracts a device major number from a raw device number.");
5179
5180static PyObject *
5181posix_major(PyObject *self, PyObject *args)
5182{
5183 int device;
5184 if (!PyArg_ParseTuple(args, "i:major", &device))
5185 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005186 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005187}
5188
5189PyDoc_STRVAR(posix_minor__doc__,
5190"minor(device) -> minor number\n\
5191Extracts a device minor number from a raw device number.");
5192
5193static PyObject *
5194posix_minor(PyObject *self, PyObject *args)
5195{
5196 int device;
5197 if (!PyArg_ParseTuple(args, "i:minor", &device))
5198 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005199 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005200}
5201
5202PyDoc_STRVAR(posix_makedev__doc__,
5203"makedev(major, minor) -> device number\n\
5204Composes a raw device number from the major and minor device numbers.");
5205
5206static PyObject *
5207posix_makedev(PyObject *self, PyObject *args)
5208{
5209 int major, minor;
5210 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5211 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005212 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005213}
5214#endif /* device macros */
5215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005216
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005217#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005218PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005219"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005220Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005221
Barry Warsaw53699e91996-12-10 23:23:01 +00005222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005223posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005224{
5225 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005226 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005227 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005228 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005229
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005230 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005231 return NULL;
5232
5233#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005234 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005235#else
5236 length = PyLong_Check(lenobj) ?
Christian Heimes217cfd12007-12-02 14:31:20 +00005237 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005238#endif
5239 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005240 return NULL;
5241
Barry Warsaw53699e91996-12-10 23:23:01 +00005242 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005243 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005244 Py_END_ALLOW_THREADS
Benjamin Peterson9053d752009-01-19 17:53:36 +00005245 if (res < 0)
5246 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005247 Py_INCREF(Py_None);
5248 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005249}
5250#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005251
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005252#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005253PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005254"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005255Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005256
Fred Drake762e2061999-08-26 17:23:54 +00005257/* Save putenv() parameters as values here, so we can collect them when they
5258 * get re-set with another call for the same key. */
5259static PyObject *posix_putenv_garbage;
5260
Tim Peters5aa91602002-01-30 05:46:57 +00005261static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005262posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005263{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005264#ifdef MS_WINDOWS
5265 wchar_t *s1, *s2;
5266 wchar_t *newenv;
5267#else
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005268 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005269 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005270#endif
Fred Drake762e2061999-08-26 17:23:54 +00005271 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005272 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005273
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005274 if (!PyArg_ParseTuple(args,
5275#ifdef MS_WINDOWS
5276 "uu:putenv",
5277#else
5278 "ss:putenv",
5279#endif
5280 &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005281 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005282
5283#if defined(PYOS_OS2)
5284 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5285 APIRET rc;
5286
Guido van Rossumd48f2521997-12-05 22:19:34 +00005287 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5288 if (rc != NO_ERROR)
5289 return os2_error(rc);
5290
5291 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5292 APIRET rc;
5293
Guido van Rossumd48f2521997-12-05 22:19:34 +00005294 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5295 if (rc != NO_ERROR)
5296 return os2_error(rc);
5297 } else {
5298#endif
Fred Drake762e2061999-08-26 17:23:54 +00005299 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005300 /* len includes space for a trailing \0; the size arg to
Christian Heimes72b710a2008-05-26 13:28:38 +00005301 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005302#ifdef MS_WINDOWS
5303 len = wcslen(s1) + wcslen(s2) + 2;
5304 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
5305#else
5306 len = strlen(s1) + strlen(s2) + 2;
Christian Heimes72b710a2008-05-26 13:28:38 +00005307 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005308#endif
Fred Drake762e2061999-08-26 17:23:54 +00005309 if (newstr == NULL)
5310 return PyErr_NoMemory();
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005311#ifdef MS_WINDOWS
5312 newenv = PyUnicode_AsUnicode(newstr);
5313 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5314 if (_wputenv(newenv)) {
5315 Py_DECREF(newstr);
5316 posix_error();
5317 return NULL;
5318 }
5319#else
Christian Heimes72b710a2008-05-26 13:28:38 +00005320 newenv = PyBytes_AS_STRING(newstr);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005321 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5322 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005323 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005324 posix_error();
5325 return NULL;
5326 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005327#endif
Fred Drake762e2061999-08-26 17:23:54 +00005328 /* Install the first arg and newstr in posix_putenv_garbage;
5329 * this will cause previous value to be collected. This has to
5330 * happen after the real putenv() call because the old value
5331 * was still accessible until then. */
5332 if (PyDict_SetItem(posix_putenv_garbage,
5333 PyTuple_GET_ITEM(args, 0), newstr)) {
5334 /* really not much we can do; just leak */
5335 PyErr_Clear();
5336 }
5337 else {
5338 Py_DECREF(newstr);
5339 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005340
5341#if defined(PYOS_OS2)
5342 }
5343#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005344 Py_INCREF(Py_None);
5345 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005346}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005347#endif /* putenv */
5348
Guido van Rossumc524d952001-10-19 01:31:59 +00005349#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005350PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005351"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005352Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005353
5354static PyObject *
5355posix_unsetenv(PyObject *self, PyObject *args)
5356{
5357 char *s1;
5358
5359 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5360 return NULL;
5361
5362 unsetenv(s1);
5363
5364 /* Remove the key from posix_putenv_garbage;
5365 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005366 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005367 * old value was still accessible until then.
5368 */
5369 if (PyDict_DelItem(posix_putenv_garbage,
5370 PyTuple_GET_ITEM(args, 0))) {
5371 /* really not much we can do; just leak */
5372 PyErr_Clear();
5373 }
5374
5375 Py_INCREF(Py_None);
5376 return Py_None;
5377}
5378#endif /* unsetenv */
5379
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005380PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005381"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005382Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005383
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005384static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005385posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005386{
5387 int code;
5388 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005389 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005390 return NULL;
5391 message = strerror(code);
5392 if (message == NULL) {
5393 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005394 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005395 return NULL;
5396 }
Neal Norwitz93c56822007-08-26 07:10:06 +00005397 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005398}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005399
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005400
Guido van Rossumc9641791998-08-04 15:26:23 +00005401#ifdef HAVE_SYS_WAIT_H
5402
Fred Drake106c1a02002-04-23 15:58:02 +00005403#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005404PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005405"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005406Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005407
5408static PyObject *
5409posix_WCOREDUMP(PyObject *self, PyObject *args)
5410{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005411 WAIT_TYPE status;
5412 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005413
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005414 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005415 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005416
5417 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005418}
5419#endif /* WCOREDUMP */
5420
5421#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005422PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005423"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005424Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005425job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005426
5427static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005428posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005429{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005430 WAIT_TYPE status;
5431 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005432
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005433 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005434 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005435
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005436 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005437}
5438#endif /* WIFCONTINUED */
5439
Guido van Rossumc9641791998-08-04 15:26:23 +00005440#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005441PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005442"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005443Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005444
5445static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005446posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005447{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005448 WAIT_TYPE status;
5449 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005450
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005451 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005452 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005453
Fred Drake106c1a02002-04-23 15:58:02 +00005454 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005455}
5456#endif /* WIFSTOPPED */
5457
5458#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005459PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005460"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005461Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005462
5463static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005464posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005465{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005466 WAIT_TYPE status;
5467 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005468
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005469 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005470 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005471
Fred Drake106c1a02002-04-23 15:58:02 +00005472 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005473}
5474#endif /* WIFSIGNALED */
5475
5476#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005477PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005478"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005479Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005480system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005481
5482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005483posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005484{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005485 WAIT_TYPE status;
5486 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005487
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005488 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005489 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005490
Fred Drake106c1a02002-04-23 15:58:02 +00005491 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005492}
5493#endif /* WIFEXITED */
5494
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005495#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005496PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005497"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005498Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005499
5500static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005501posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005502{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005503 WAIT_TYPE status;
5504 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005505
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005506 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005507 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005508
Guido van Rossumc9641791998-08-04 15:26:23 +00005509 return Py_BuildValue("i", WEXITSTATUS(status));
5510}
5511#endif /* WEXITSTATUS */
5512
5513#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005514PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005515"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005516Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005517value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005518
5519static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005520posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005521{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005522 WAIT_TYPE status;
5523 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005524
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005525 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005526 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005527
Guido van Rossumc9641791998-08-04 15:26:23 +00005528 return Py_BuildValue("i", WTERMSIG(status));
5529}
5530#endif /* WTERMSIG */
5531
5532#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005533PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005534"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005535Return the signal that stopped the process that provided\n\
5536the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005537
5538static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005539posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005540{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005541 WAIT_TYPE status;
5542 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005543
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005544 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005545 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005546
Guido van Rossumc9641791998-08-04 15:26:23 +00005547 return Py_BuildValue("i", WSTOPSIG(status));
5548}
5549#endif /* WSTOPSIG */
5550
5551#endif /* HAVE_SYS_WAIT_H */
5552
5553
Thomas Wouters477c8d52006-05-27 19:21:47 +00005554#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005555#ifdef _SCO_DS
5556/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5557 needed definitions in sys/statvfs.h */
5558#define _SVID3
5559#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005560#include <sys/statvfs.h>
5561
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005562static PyObject*
5563_pystatvfs_fromstructstatvfs(struct statvfs st) {
5564 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5565 if (v == NULL)
5566 return NULL;
5567
5568#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005569 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5570 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5571 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
5572 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
5573 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
5574 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
5575 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
5576 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
5577 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5578 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005579#else
Christian Heimes217cfd12007-12-02 14:31:20 +00005580 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5581 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005582 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005583 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005584 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005585 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005586 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005587 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005588 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005589 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005590 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005591 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005592 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005593 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Christian Heimes217cfd12007-12-02 14:31:20 +00005594 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5595 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005596#endif
5597
5598 return v;
5599}
5600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005601PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005602"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005603Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005604
5605static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005606posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005607{
5608 int fd, res;
5609 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005610
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005611 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005612 return NULL;
5613 Py_BEGIN_ALLOW_THREADS
5614 res = fstatvfs(fd, &st);
5615 Py_END_ALLOW_THREADS
5616 if (res != 0)
5617 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005618
5619 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005620}
Thomas Wouters477c8d52006-05-27 19:21:47 +00005621#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005622
5623
Thomas Wouters477c8d52006-05-27 19:21:47 +00005624#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005625#include <sys/statvfs.h>
5626
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005627PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005628"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005629Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005630
5631static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005632posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005633{
5634 char *path;
5635 int res;
5636 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005637 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005638 return NULL;
5639 Py_BEGIN_ALLOW_THREADS
5640 res = statvfs(path, &st);
5641 Py_END_ALLOW_THREADS
5642 if (res != 0)
5643 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005644
5645 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005646}
5647#endif /* HAVE_STATVFS */
5648
Fred Drakec9680921999-12-13 16:37:25 +00005649/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5650 * It maps strings representing configuration variable names to
5651 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005652 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005653 * rarely-used constants. There are three separate tables that use
5654 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005655 *
5656 * This code is always included, even if none of the interfaces that
5657 * need it are included. The #if hackery needed to avoid it would be
5658 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005659 */
5660struct constdef {
5661 char *name;
5662 long value;
5663};
5664
Fred Drake12c6e2d1999-12-14 21:25:03 +00005665static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005666conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005667 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005668{
Christian Heimes217cfd12007-12-02 14:31:20 +00005669 if (PyLong_Check(arg)) {
5670 *valuep = PyLong_AS_LONG(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005671 return 1;
5672 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00005673 else {
Fred Drake12c6e2d1999-12-14 21:25:03 +00005674 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005675 size_t lo = 0;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005676 size_t mid;
Fred Drake699f3522000-06-29 21:12:41 +00005677 size_t hi = tablesize;
5678 int cmp;
Guido van Rossumbce56a62007-05-10 18:04:33 +00005679 const char *confname;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005680 if (!PyUnicode_Check(arg)) {
Guido van Rossumbce56a62007-05-10 18:04:33 +00005681 PyErr_SetString(PyExc_TypeError,
5682 "configuration names must be strings or integers");
5683 return 0;
5684 }
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00005685 confname = _PyUnicode_AsString(arg);
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005686 if (confname == NULL)
5687 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005688 while (lo < hi) {
5689 mid = (lo + hi) / 2;
5690 cmp = strcmp(confname, table[mid].name);
5691 if (cmp < 0)
5692 hi = mid;
5693 else if (cmp > 0)
5694 lo = mid + 1;
5695 else {
5696 *valuep = table[mid].value;
5697 return 1;
5698 }
5699 }
5700 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Guido van Rossumbce56a62007-05-10 18:04:33 +00005701 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005702 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005703}
5704
5705
5706#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5707static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005708#ifdef _PC_ABI_AIO_XFER_MAX
5709 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5710#endif
5711#ifdef _PC_ABI_ASYNC_IO
5712 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5713#endif
Fred Drakec9680921999-12-13 16:37:25 +00005714#ifdef _PC_ASYNC_IO
5715 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5716#endif
5717#ifdef _PC_CHOWN_RESTRICTED
5718 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5719#endif
5720#ifdef _PC_FILESIZEBITS
5721 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5722#endif
5723#ifdef _PC_LAST
5724 {"PC_LAST", _PC_LAST},
5725#endif
5726#ifdef _PC_LINK_MAX
5727 {"PC_LINK_MAX", _PC_LINK_MAX},
5728#endif
5729#ifdef _PC_MAX_CANON
5730 {"PC_MAX_CANON", _PC_MAX_CANON},
5731#endif
5732#ifdef _PC_MAX_INPUT
5733 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5734#endif
5735#ifdef _PC_NAME_MAX
5736 {"PC_NAME_MAX", _PC_NAME_MAX},
5737#endif
5738#ifdef _PC_NO_TRUNC
5739 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5740#endif
5741#ifdef _PC_PATH_MAX
5742 {"PC_PATH_MAX", _PC_PATH_MAX},
5743#endif
5744#ifdef _PC_PIPE_BUF
5745 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5746#endif
5747#ifdef _PC_PRIO_IO
5748 {"PC_PRIO_IO", _PC_PRIO_IO},
5749#endif
5750#ifdef _PC_SOCK_MAXBUF
5751 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5752#endif
5753#ifdef _PC_SYNC_IO
5754 {"PC_SYNC_IO", _PC_SYNC_IO},
5755#endif
5756#ifdef _PC_VDISABLE
5757 {"PC_VDISABLE", _PC_VDISABLE},
5758#endif
5759};
5760
Fred Drakec9680921999-12-13 16:37:25 +00005761static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005762conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005763{
5764 return conv_confname(arg, valuep, posix_constants_pathconf,
5765 sizeof(posix_constants_pathconf)
5766 / sizeof(struct constdef));
5767}
5768#endif
5769
5770#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005771PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005772"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005773Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005774If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005775
5776static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005777posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005778{
5779 PyObject *result = NULL;
5780 int name, fd;
5781
Fred Drake12c6e2d1999-12-14 21:25:03 +00005782 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5783 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005784 long limit;
5785
5786 errno = 0;
5787 limit = fpathconf(fd, name);
5788 if (limit == -1 && errno != 0)
5789 posix_error();
5790 else
Christian Heimes217cfd12007-12-02 14:31:20 +00005791 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005792 }
5793 return result;
5794}
5795#endif
5796
5797
5798#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005799PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005800"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005801Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005802If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005803
5804static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005805posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005806{
5807 PyObject *result = NULL;
5808 int name;
5809 char *path;
5810
5811 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5812 conv_path_confname, &name)) {
5813 long limit;
5814
5815 errno = 0;
5816 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005817 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005818 if (errno == EINVAL)
5819 /* could be a path or name problem */
5820 posix_error();
5821 else
5822 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005823 }
Fred Drakec9680921999-12-13 16:37:25 +00005824 else
Christian Heimes217cfd12007-12-02 14:31:20 +00005825 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005826 }
5827 return result;
5828}
5829#endif
5830
5831#ifdef HAVE_CONFSTR
5832static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005833#ifdef _CS_ARCHITECTURE
5834 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5835#endif
5836#ifdef _CS_HOSTNAME
5837 {"CS_HOSTNAME", _CS_HOSTNAME},
5838#endif
5839#ifdef _CS_HW_PROVIDER
5840 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5841#endif
5842#ifdef _CS_HW_SERIAL
5843 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5844#endif
5845#ifdef _CS_INITTAB_NAME
5846 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5847#endif
Fred Drakec9680921999-12-13 16:37:25 +00005848#ifdef _CS_LFS64_CFLAGS
5849 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5850#endif
5851#ifdef _CS_LFS64_LDFLAGS
5852 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5853#endif
5854#ifdef _CS_LFS64_LIBS
5855 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5856#endif
5857#ifdef _CS_LFS64_LINTFLAGS
5858 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5859#endif
5860#ifdef _CS_LFS_CFLAGS
5861 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5862#endif
5863#ifdef _CS_LFS_LDFLAGS
5864 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5865#endif
5866#ifdef _CS_LFS_LIBS
5867 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5868#endif
5869#ifdef _CS_LFS_LINTFLAGS
5870 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5871#endif
Fred Draked86ed291999-12-15 15:34:33 +00005872#ifdef _CS_MACHINE
5873 {"CS_MACHINE", _CS_MACHINE},
5874#endif
Fred Drakec9680921999-12-13 16:37:25 +00005875#ifdef _CS_PATH
5876 {"CS_PATH", _CS_PATH},
5877#endif
Fred Draked86ed291999-12-15 15:34:33 +00005878#ifdef _CS_RELEASE
5879 {"CS_RELEASE", _CS_RELEASE},
5880#endif
5881#ifdef _CS_SRPC_DOMAIN
5882 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5883#endif
5884#ifdef _CS_SYSNAME
5885 {"CS_SYSNAME", _CS_SYSNAME},
5886#endif
5887#ifdef _CS_VERSION
5888 {"CS_VERSION", _CS_VERSION},
5889#endif
Fred Drakec9680921999-12-13 16:37:25 +00005890#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5891 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5892#endif
5893#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5894 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5895#endif
5896#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5897 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5898#endif
5899#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5900 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5901#endif
5902#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5903 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5904#endif
5905#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5906 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5907#endif
5908#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5909 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5910#endif
5911#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5912 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5913#endif
5914#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5915 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5916#endif
5917#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5918 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5919#endif
5920#ifdef _CS_XBS5_LP64_OFF64_LIBS
5921 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5922#endif
5923#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5924 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5925#endif
5926#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5927 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5928#endif
5929#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5930 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5931#endif
5932#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5933 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5934#endif
5935#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5936 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5937#endif
Fred Draked86ed291999-12-15 15:34:33 +00005938#ifdef _MIPS_CS_AVAIL_PROCESSORS
5939 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5940#endif
5941#ifdef _MIPS_CS_BASE
5942 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5943#endif
5944#ifdef _MIPS_CS_HOSTID
5945 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5946#endif
5947#ifdef _MIPS_CS_HW_NAME
5948 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5949#endif
5950#ifdef _MIPS_CS_NUM_PROCESSORS
5951 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5952#endif
5953#ifdef _MIPS_CS_OSREL_MAJ
5954 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5955#endif
5956#ifdef _MIPS_CS_OSREL_MIN
5957 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5958#endif
5959#ifdef _MIPS_CS_OSREL_PATCH
5960 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5961#endif
5962#ifdef _MIPS_CS_OS_NAME
5963 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5964#endif
5965#ifdef _MIPS_CS_OS_PROVIDER
5966 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5967#endif
5968#ifdef _MIPS_CS_PROCESSORS
5969 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5970#endif
5971#ifdef _MIPS_CS_SERIAL
5972 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5973#endif
5974#ifdef _MIPS_CS_VENDOR
5975 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5976#endif
Fred Drakec9680921999-12-13 16:37:25 +00005977};
5978
5979static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005980conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005981{
5982 return conv_confname(arg, valuep, posix_constants_confstr,
5983 sizeof(posix_constants_confstr)
5984 / sizeof(struct constdef));
5985}
5986
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005987PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005988"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005989Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005990
5991static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005992posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005993{
5994 PyObject *result = NULL;
5995 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005996 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00005997
5998 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005999 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006000
Fred Drakec9680921999-12-13 16:37:25 +00006001 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006002 len = confstr(name, buffer, sizeof(buffer));
6003 if (len == 0) {
6004 if (errno) {
6005 posix_error();
6006 }
6007 else {
6008 result = Py_None;
6009 Py_INCREF(Py_None);
6010 }
Fred Drakec9680921999-12-13 16:37:25 +00006011 }
6012 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006013 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00006014 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006015 if (result != NULL)
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00006016 confstr(name, _PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00006017 }
6018 else
Neal Norwitz93c56822007-08-26 07:10:06 +00006019 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006020 }
6021 }
6022 return result;
6023}
6024#endif
6025
6026
6027#ifdef HAVE_SYSCONF
6028static struct constdef posix_constants_sysconf[] = {
6029#ifdef _SC_2_CHAR_TERM
6030 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6031#endif
6032#ifdef _SC_2_C_BIND
6033 {"SC_2_C_BIND", _SC_2_C_BIND},
6034#endif
6035#ifdef _SC_2_C_DEV
6036 {"SC_2_C_DEV", _SC_2_C_DEV},
6037#endif
6038#ifdef _SC_2_C_VERSION
6039 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6040#endif
6041#ifdef _SC_2_FORT_DEV
6042 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6043#endif
6044#ifdef _SC_2_FORT_RUN
6045 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6046#endif
6047#ifdef _SC_2_LOCALEDEF
6048 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6049#endif
6050#ifdef _SC_2_SW_DEV
6051 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6052#endif
6053#ifdef _SC_2_UPE
6054 {"SC_2_UPE", _SC_2_UPE},
6055#endif
6056#ifdef _SC_2_VERSION
6057 {"SC_2_VERSION", _SC_2_VERSION},
6058#endif
Fred Draked86ed291999-12-15 15:34:33 +00006059#ifdef _SC_ABI_ASYNCHRONOUS_IO
6060 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6061#endif
6062#ifdef _SC_ACL
6063 {"SC_ACL", _SC_ACL},
6064#endif
Fred Drakec9680921999-12-13 16:37:25 +00006065#ifdef _SC_AIO_LISTIO_MAX
6066 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6067#endif
Fred Drakec9680921999-12-13 16:37:25 +00006068#ifdef _SC_AIO_MAX
6069 {"SC_AIO_MAX", _SC_AIO_MAX},
6070#endif
6071#ifdef _SC_AIO_PRIO_DELTA_MAX
6072 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6073#endif
6074#ifdef _SC_ARG_MAX
6075 {"SC_ARG_MAX", _SC_ARG_MAX},
6076#endif
6077#ifdef _SC_ASYNCHRONOUS_IO
6078 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6079#endif
6080#ifdef _SC_ATEXIT_MAX
6081 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6082#endif
Fred Draked86ed291999-12-15 15:34:33 +00006083#ifdef _SC_AUDIT
6084 {"SC_AUDIT", _SC_AUDIT},
6085#endif
Fred Drakec9680921999-12-13 16:37:25 +00006086#ifdef _SC_AVPHYS_PAGES
6087 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6088#endif
6089#ifdef _SC_BC_BASE_MAX
6090 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6091#endif
6092#ifdef _SC_BC_DIM_MAX
6093 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6094#endif
6095#ifdef _SC_BC_SCALE_MAX
6096 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6097#endif
6098#ifdef _SC_BC_STRING_MAX
6099 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6100#endif
Fred Draked86ed291999-12-15 15:34:33 +00006101#ifdef _SC_CAP
6102 {"SC_CAP", _SC_CAP},
6103#endif
Fred Drakec9680921999-12-13 16:37:25 +00006104#ifdef _SC_CHARCLASS_NAME_MAX
6105 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6106#endif
6107#ifdef _SC_CHAR_BIT
6108 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6109#endif
6110#ifdef _SC_CHAR_MAX
6111 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6112#endif
6113#ifdef _SC_CHAR_MIN
6114 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6115#endif
6116#ifdef _SC_CHILD_MAX
6117 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6118#endif
6119#ifdef _SC_CLK_TCK
6120 {"SC_CLK_TCK", _SC_CLK_TCK},
6121#endif
6122#ifdef _SC_COHER_BLKSZ
6123 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6124#endif
6125#ifdef _SC_COLL_WEIGHTS_MAX
6126 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6127#endif
6128#ifdef _SC_DCACHE_ASSOC
6129 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6130#endif
6131#ifdef _SC_DCACHE_BLKSZ
6132 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6133#endif
6134#ifdef _SC_DCACHE_LINESZ
6135 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6136#endif
6137#ifdef _SC_DCACHE_SZ
6138 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6139#endif
6140#ifdef _SC_DCACHE_TBLKSZ
6141 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6142#endif
6143#ifdef _SC_DELAYTIMER_MAX
6144 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6145#endif
6146#ifdef _SC_EQUIV_CLASS_MAX
6147 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6148#endif
6149#ifdef _SC_EXPR_NEST_MAX
6150 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6151#endif
6152#ifdef _SC_FSYNC
6153 {"SC_FSYNC", _SC_FSYNC},
6154#endif
6155#ifdef _SC_GETGR_R_SIZE_MAX
6156 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6157#endif
6158#ifdef _SC_GETPW_R_SIZE_MAX
6159 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6160#endif
6161#ifdef _SC_ICACHE_ASSOC
6162 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6163#endif
6164#ifdef _SC_ICACHE_BLKSZ
6165 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6166#endif
6167#ifdef _SC_ICACHE_LINESZ
6168 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6169#endif
6170#ifdef _SC_ICACHE_SZ
6171 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6172#endif
Fred Draked86ed291999-12-15 15:34:33 +00006173#ifdef _SC_INF
6174 {"SC_INF", _SC_INF},
6175#endif
Fred Drakec9680921999-12-13 16:37:25 +00006176#ifdef _SC_INT_MAX
6177 {"SC_INT_MAX", _SC_INT_MAX},
6178#endif
6179#ifdef _SC_INT_MIN
6180 {"SC_INT_MIN", _SC_INT_MIN},
6181#endif
6182#ifdef _SC_IOV_MAX
6183 {"SC_IOV_MAX", _SC_IOV_MAX},
6184#endif
Fred Draked86ed291999-12-15 15:34:33 +00006185#ifdef _SC_IP_SECOPTS
6186 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6187#endif
Fred Drakec9680921999-12-13 16:37:25 +00006188#ifdef _SC_JOB_CONTROL
6189 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6190#endif
Fred Draked86ed291999-12-15 15:34:33 +00006191#ifdef _SC_KERN_POINTERS
6192 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6193#endif
6194#ifdef _SC_KERN_SIM
6195 {"SC_KERN_SIM", _SC_KERN_SIM},
6196#endif
Fred Drakec9680921999-12-13 16:37:25 +00006197#ifdef _SC_LINE_MAX
6198 {"SC_LINE_MAX", _SC_LINE_MAX},
6199#endif
6200#ifdef _SC_LOGIN_NAME_MAX
6201 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6202#endif
6203#ifdef _SC_LOGNAME_MAX
6204 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6205#endif
6206#ifdef _SC_LONG_BIT
6207 {"SC_LONG_BIT", _SC_LONG_BIT},
6208#endif
Fred Draked86ed291999-12-15 15:34:33 +00006209#ifdef _SC_MAC
6210 {"SC_MAC", _SC_MAC},
6211#endif
Fred Drakec9680921999-12-13 16:37:25 +00006212#ifdef _SC_MAPPED_FILES
6213 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6214#endif
6215#ifdef _SC_MAXPID
6216 {"SC_MAXPID", _SC_MAXPID},
6217#endif
6218#ifdef _SC_MB_LEN_MAX
6219 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6220#endif
6221#ifdef _SC_MEMLOCK
6222 {"SC_MEMLOCK", _SC_MEMLOCK},
6223#endif
6224#ifdef _SC_MEMLOCK_RANGE
6225 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6226#endif
6227#ifdef _SC_MEMORY_PROTECTION
6228 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6229#endif
6230#ifdef _SC_MESSAGE_PASSING
6231 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6232#endif
Fred Draked86ed291999-12-15 15:34:33 +00006233#ifdef _SC_MMAP_FIXED_ALIGNMENT
6234 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6235#endif
Fred Drakec9680921999-12-13 16:37:25 +00006236#ifdef _SC_MQ_OPEN_MAX
6237 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6238#endif
6239#ifdef _SC_MQ_PRIO_MAX
6240 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6241#endif
Fred Draked86ed291999-12-15 15:34:33 +00006242#ifdef _SC_NACLS_MAX
6243 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6244#endif
Fred Drakec9680921999-12-13 16:37:25 +00006245#ifdef _SC_NGROUPS_MAX
6246 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6247#endif
6248#ifdef _SC_NL_ARGMAX
6249 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6250#endif
6251#ifdef _SC_NL_LANGMAX
6252 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6253#endif
6254#ifdef _SC_NL_MSGMAX
6255 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6256#endif
6257#ifdef _SC_NL_NMAX
6258 {"SC_NL_NMAX", _SC_NL_NMAX},
6259#endif
6260#ifdef _SC_NL_SETMAX
6261 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6262#endif
6263#ifdef _SC_NL_TEXTMAX
6264 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6265#endif
6266#ifdef _SC_NPROCESSORS_CONF
6267 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6268#endif
6269#ifdef _SC_NPROCESSORS_ONLN
6270 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6271#endif
Fred Draked86ed291999-12-15 15:34:33 +00006272#ifdef _SC_NPROC_CONF
6273 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6274#endif
6275#ifdef _SC_NPROC_ONLN
6276 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6277#endif
Fred Drakec9680921999-12-13 16:37:25 +00006278#ifdef _SC_NZERO
6279 {"SC_NZERO", _SC_NZERO},
6280#endif
6281#ifdef _SC_OPEN_MAX
6282 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6283#endif
6284#ifdef _SC_PAGESIZE
6285 {"SC_PAGESIZE", _SC_PAGESIZE},
6286#endif
6287#ifdef _SC_PAGE_SIZE
6288 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6289#endif
6290#ifdef _SC_PASS_MAX
6291 {"SC_PASS_MAX", _SC_PASS_MAX},
6292#endif
6293#ifdef _SC_PHYS_PAGES
6294 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6295#endif
6296#ifdef _SC_PII
6297 {"SC_PII", _SC_PII},
6298#endif
6299#ifdef _SC_PII_INTERNET
6300 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6301#endif
6302#ifdef _SC_PII_INTERNET_DGRAM
6303 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6304#endif
6305#ifdef _SC_PII_INTERNET_STREAM
6306 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6307#endif
6308#ifdef _SC_PII_OSI
6309 {"SC_PII_OSI", _SC_PII_OSI},
6310#endif
6311#ifdef _SC_PII_OSI_CLTS
6312 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6313#endif
6314#ifdef _SC_PII_OSI_COTS
6315 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6316#endif
6317#ifdef _SC_PII_OSI_M
6318 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6319#endif
6320#ifdef _SC_PII_SOCKET
6321 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6322#endif
6323#ifdef _SC_PII_XTI
6324 {"SC_PII_XTI", _SC_PII_XTI},
6325#endif
6326#ifdef _SC_POLL
6327 {"SC_POLL", _SC_POLL},
6328#endif
6329#ifdef _SC_PRIORITIZED_IO
6330 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6331#endif
6332#ifdef _SC_PRIORITY_SCHEDULING
6333 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6334#endif
6335#ifdef _SC_REALTIME_SIGNALS
6336 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6337#endif
6338#ifdef _SC_RE_DUP_MAX
6339 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6340#endif
6341#ifdef _SC_RTSIG_MAX
6342 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6343#endif
6344#ifdef _SC_SAVED_IDS
6345 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6346#endif
6347#ifdef _SC_SCHAR_MAX
6348 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6349#endif
6350#ifdef _SC_SCHAR_MIN
6351 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6352#endif
6353#ifdef _SC_SELECT
6354 {"SC_SELECT", _SC_SELECT},
6355#endif
6356#ifdef _SC_SEMAPHORES
6357 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6358#endif
6359#ifdef _SC_SEM_NSEMS_MAX
6360 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6361#endif
6362#ifdef _SC_SEM_VALUE_MAX
6363 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6364#endif
6365#ifdef _SC_SHARED_MEMORY_OBJECTS
6366 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6367#endif
6368#ifdef _SC_SHRT_MAX
6369 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6370#endif
6371#ifdef _SC_SHRT_MIN
6372 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6373#endif
6374#ifdef _SC_SIGQUEUE_MAX
6375 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6376#endif
6377#ifdef _SC_SIGRT_MAX
6378 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6379#endif
6380#ifdef _SC_SIGRT_MIN
6381 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6382#endif
Fred Draked86ed291999-12-15 15:34:33 +00006383#ifdef _SC_SOFTPOWER
6384 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6385#endif
Fred Drakec9680921999-12-13 16:37:25 +00006386#ifdef _SC_SPLIT_CACHE
6387 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6388#endif
6389#ifdef _SC_SSIZE_MAX
6390 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6391#endif
6392#ifdef _SC_STACK_PROT
6393 {"SC_STACK_PROT", _SC_STACK_PROT},
6394#endif
6395#ifdef _SC_STREAM_MAX
6396 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6397#endif
6398#ifdef _SC_SYNCHRONIZED_IO
6399 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6400#endif
6401#ifdef _SC_THREADS
6402 {"SC_THREADS", _SC_THREADS},
6403#endif
6404#ifdef _SC_THREAD_ATTR_STACKADDR
6405 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6406#endif
6407#ifdef _SC_THREAD_ATTR_STACKSIZE
6408 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6409#endif
6410#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6411 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6412#endif
6413#ifdef _SC_THREAD_KEYS_MAX
6414 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6415#endif
6416#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6417 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6418#endif
6419#ifdef _SC_THREAD_PRIO_INHERIT
6420 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6421#endif
6422#ifdef _SC_THREAD_PRIO_PROTECT
6423 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6424#endif
6425#ifdef _SC_THREAD_PROCESS_SHARED
6426 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6427#endif
6428#ifdef _SC_THREAD_SAFE_FUNCTIONS
6429 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6430#endif
6431#ifdef _SC_THREAD_STACK_MIN
6432 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6433#endif
6434#ifdef _SC_THREAD_THREADS_MAX
6435 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6436#endif
6437#ifdef _SC_TIMERS
6438 {"SC_TIMERS", _SC_TIMERS},
6439#endif
6440#ifdef _SC_TIMER_MAX
6441 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6442#endif
6443#ifdef _SC_TTY_NAME_MAX
6444 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6445#endif
6446#ifdef _SC_TZNAME_MAX
6447 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6448#endif
6449#ifdef _SC_T_IOV_MAX
6450 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6451#endif
6452#ifdef _SC_UCHAR_MAX
6453 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6454#endif
6455#ifdef _SC_UINT_MAX
6456 {"SC_UINT_MAX", _SC_UINT_MAX},
6457#endif
6458#ifdef _SC_UIO_MAXIOV
6459 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6460#endif
6461#ifdef _SC_ULONG_MAX
6462 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6463#endif
6464#ifdef _SC_USHRT_MAX
6465 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6466#endif
6467#ifdef _SC_VERSION
6468 {"SC_VERSION", _SC_VERSION},
6469#endif
6470#ifdef _SC_WORD_BIT
6471 {"SC_WORD_BIT", _SC_WORD_BIT},
6472#endif
6473#ifdef _SC_XBS5_ILP32_OFF32
6474 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6475#endif
6476#ifdef _SC_XBS5_ILP32_OFFBIG
6477 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6478#endif
6479#ifdef _SC_XBS5_LP64_OFF64
6480 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6481#endif
6482#ifdef _SC_XBS5_LPBIG_OFFBIG
6483 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6484#endif
6485#ifdef _SC_XOPEN_CRYPT
6486 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6487#endif
6488#ifdef _SC_XOPEN_ENH_I18N
6489 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6490#endif
6491#ifdef _SC_XOPEN_LEGACY
6492 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6493#endif
6494#ifdef _SC_XOPEN_REALTIME
6495 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6496#endif
6497#ifdef _SC_XOPEN_REALTIME_THREADS
6498 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6499#endif
6500#ifdef _SC_XOPEN_SHM
6501 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6502#endif
6503#ifdef _SC_XOPEN_UNIX
6504 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6505#endif
6506#ifdef _SC_XOPEN_VERSION
6507 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6508#endif
6509#ifdef _SC_XOPEN_XCU_VERSION
6510 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6511#endif
6512#ifdef _SC_XOPEN_XPG2
6513 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6514#endif
6515#ifdef _SC_XOPEN_XPG3
6516 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6517#endif
6518#ifdef _SC_XOPEN_XPG4
6519 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6520#endif
6521};
6522
6523static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006524conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006525{
6526 return conv_confname(arg, valuep, posix_constants_sysconf,
6527 sizeof(posix_constants_sysconf)
6528 / sizeof(struct constdef));
6529}
6530
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006531PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006532"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006533Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006534
6535static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006536posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006537{
6538 PyObject *result = NULL;
6539 int name;
6540
6541 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6542 int value;
6543
6544 errno = 0;
6545 value = sysconf(name);
6546 if (value == -1 && errno != 0)
6547 posix_error();
6548 else
Christian Heimes217cfd12007-12-02 14:31:20 +00006549 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00006550 }
6551 return result;
6552}
6553#endif
6554
6555
Fred Drakebec628d1999-12-15 18:31:10 +00006556/* This code is used to ensure that the tables of configuration value names
6557 * are in sorted order as required by conv_confname(), and also to build the
6558 * the exported dictionaries that are used to publish information about the
6559 * names available on the host platform.
6560 *
6561 * Sorting the table at runtime ensures that the table is properly ordered
6562 * when used, even for platforms we're not able to test on. It also makes
6563 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006564 */
Fred Drakebec628d1999-12-15 18:31:10 +00006565
6566static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006567cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006568{
6569 const struct constdef *c1 =
6570 (const struct constdef *) v1;
6571 const struct constdef *c2 =
6572 (const struct constdef *) v2;
6573
6574 return strcmp(c1->name, c2->name);
6575}
6576
6577static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006578setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006579 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006580{
Fred Drakebec628d1999-12-15 18:31:10 +00006581 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006582 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006583
6584 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6585 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006586 if (d == NULL)
6587 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006588
Barry Warsaw3155db32000-04-13 15:20:40 +00006589 for (i=0; i < tablesize; ++i) {
Christian Heimes217cfd12007-12-02 14:31:20 +00006590 PyObject *o = PyLong_FromLong(table[i].value);
Barry Warsaw3155db32000-04-13 15:20:40 +00006591 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6592 Py_XDECREF(o);
6593 Py_DECREF(d);
6594 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006595 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006596 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006597 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006598 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006599}
6600
Fred Drakebec628d1999-12-15 18:31:10 +00006601/* Return -1 on failure, 0 on success. */
6602static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006603setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006604{
6605#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006606 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006607 sizeof(posix_constants_pathconf)
6608 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006609 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006610 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006611#endif
6612#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006613 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006614 sizeof(posix_constants_confstr)
6615 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006616 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006617 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006618#endif
6619#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006620 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006621 sizeof(posix_constants_sysconf)
6622 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006623 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006624 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006625#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006626 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006627}
Fred Draked86ed291999-12-15 15:34:33 +00006628
6629
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006630PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006631"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006632Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006633in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006634
6635static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006636posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006637{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006638 abort();
6639 /*NOTREACHED*/
6640 Py_FatalError("abort() called from Python code didn't abort!");
6641 return NULL;
6642}
Fred Drakebec628d1999-12-15 18:31:10 +00006643
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006644#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006645PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00006646"startfile(filepath [, operation]) - Start a file with its associated\n\
6647application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006648\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00006649When \"operation\" is not specified or \"open\", this acts like\n\
6650double-clicking the file in Explorer, or giving the file name as an\n\
6651argument to the DOS \"start\" command: the file is opened with whatever\n\
6652application (if any) its extension is associated.\n\
6653When another \"operation\" is given, it specifies what should be done with\n\
6654the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006655\n\
6656startfile returns as soon as the associated application is launched.\n\
6657There is no option to wait for the application to close, and no way\n\
6658to retrieve the application's exit status.\n\
6659\n\
6660The filepath is relative to the current directory. If you want to use\n\
6661an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006662the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006663
6664static PyObject *
6665win32_startfile(PyObject *self, PyObject *args)
6666{
6667 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00006668 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006669 HINSTANCE rc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006670#ifdef Py_WIN_WIDE_FILENAMES
6671 if (unicode_file_names()) {
6672 PyObject *unipath, *woperation = NULL;
6673 if (!PyArg_ParseTuple(args, "U|s:startfile",
6674 &unipath, &operation)) {
6675 PyErr_Clear();
6676 goto normal;
6677 }
6678
6679
6680 if (operation) {
6681 woperation = PyUnicode_DecodeASCII(operation,
6682 strlen(operation), NULL);
6683 if (!woperation) {
6684 PyErr_Clear();
6685 operation = NULL;
6686 goto normal;
6687 }
6688 }
6689
6690 Py_BEGIN_ALLOW_THREADS
6691 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6692 PyUnicode_AS_UNICODE(unipath),
6693 NULL, NULL, SW_SHOWNORMAL);
6694 Py_END_ALLOW_THREADS
6695
6696 Py_XDECREF(woperation);
6697 if (rc <= (HINSTANCE)32) {
6698 PyObject *errval = win32_error_unicode("startfile",
6699 PyUnicode_AS_UNICODE(unipath));
6700 return errval;
6701 }
6702 Py_INCREF(Py_None);
6703 return Py_None;
6704 }
6705#endif
6706
6707normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00006708 if (!PyArg_ParseTuple(args, "et|s:startfile",
6709 Py_FileSystemDefaultEncoding, &filepath,
6710 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00006711 return NULL;
6712 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00006713 rc = ShellExecute((HWND)0, operation, filepath,
6714 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006715 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00006716 if (rc <= (HINSTANCE)32) {
6717 PyObject *errval = win32_error("startfile", filepath);
6718 PyMem_Free(filepath);
6719 return errval;
6720 }
6721 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006722 Py_INCREF(Py_None);
6723 return Py_None;
6724}
6725#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006726
Martin v. Löwis438b5342002-12-27 10:16:42 +00006727#ifdef HAVE_GETLOADAVG
6728PyDoc_STRVAR(posix_getloadavg__doc__,
6729"getloadavg() -> (float, float, float)\n\n\
6730Return the number of processes in the system run queue averaged over\n\
6731the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6732was unobtainable");
6733
6734static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006735posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006736{
6737 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006738 if (getloadavg(loadavg, 3)!=3) {
6739 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6740 return NULL;
6741 } else
6742 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6743}
6744#endif
6745
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006746#ifdef MS_WINDOWS
6747
6748PyDoc_STRVAR(win32_urandom__doc__,
6749"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006750Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006751
6752typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6753 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6754 DWORD dwFlags );
6755typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6756 BYTE *pbBuffer );
6757
6758static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00006759/* This handle is never explicitly released. Instead, the operating
6760 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006761static HCRYPTPROV hCryptProv = 0;
6762
Tim Peters4ad82172004-08-30 17:02:04 +00006763static PyObject*
6764win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006765{
Tim Petersd3115382004-08-30 17:36:46 +00006766 int howMany;
6767 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006768
Tim Peters4ad82172004-08-30 17:02:04 +00006769 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00006770 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00006771 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00006772 if (howMany < 0)
6773 return PyErr_Format(PyExc_ValueError,
6774 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006775
Tim Peters4ad82172004-08-30 17:02:04 +00006776 if (hCryptProv == 0) {
6777 HINSTANCE hAdvAPI32 = NULL;
6778 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006779
Tim Peters4ad82172004-08-30 17:02:04 +00006780 /* Obtain handle to the DLL containing CryptoAPI
6781 This should not fail */
6782 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6783 if(hAdvAPI32 == NULL)
6784 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006785
Tim Peters4ad82172004-08-30 17:02:04 +00006786 /* Obtain pointers to the CryptoAPI functions
6787 This will fail on some early versions of Win95 */
6788 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6789 hAdvAPI32,
6790 "CryptAcquireContextA");
6791 if (pCryptAcquireContext == NULL)
6792 return PyErr_Format(PyExc_NotImplementedError,
6793 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006794
Tim Peters4ad82172004-08-30 17:02:04 +00006795 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6796 hAdvAPI32, "CryptGenRandom");
Thomas Wouters89f507f2006-12-13 04:49:30 +00006797 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00006798 return PyErr_Format(PyExc_NotImplementedError,
6799 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006800
Tim Peters4ad82172004-08-30 17:02:04 +00006801 /* Acquire context */
6802 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
6803 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
6804 return win32_error("CryptAcquireContext", NULL);
6805 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006806
Tim Peters4ad82172004-08-30 17:02:04 +00006807 /* Allocate bytes */
Christian Heimes72b710a2008-05-26 13:28:38 +00006808 result = PyBytes_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00006809 if (result != NULL) {
6810 /* Get random data */
Amaury Forgeot d'Arca05ada32008-07-21 21:13:14 +00006811 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00006812 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Christian Heimes72b710a2008-05-26 13:28:38 +00006813 PyBytes_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00006814 Py_DECREF(result);
6815 return win32_error("CryptGenRandom", NULL);
6816 }
Tim Peters4ad82172004-08-30 17:02:04 +00006817 }
Tim Petersd3115382004-08-30 17:36:46 +00006818 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006819}
6820#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00006821
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006822PyDoc_STRVAR(device_encoding__doc__,
6823"device_encoding(fd) -> str\n\n\
6824Return a string describing the encoding of the device\n\
6825if the output is a terminal; else return None.");
6826
6827static PyObject *
6828device_encoding(PyObject *self, PyObject *args)
6829{
6830 int fd;
6831 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
6832 return NULL;
Kristján Valur Jónsson649170b2009-03-24 14:15:49 +00006833 if (!_PyVerify_fd(fd) || !isatty(fd)) {
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006834 Py_INCREF(Py_None);
6835 return Py_None;
6836 }
6837#if defined(MS_WINDOWS) || defined(MS_WIN64)
6838 if (fd == 0) {
6839 char buf[100];
6840 sprintf(buf, "cp%d", GetConsoleCP());
6841 return PyUnicode_FromString(buf);
6842 }
6843 if (fd == 1 || fd == 2) {
6844 char buf[100];
6845 sprintf(buf, "cp%d", GetConsoleOutputCP());
6846 return PyUnicode_FromString(buf);
6847 }
6848#elif defined(CODESET)
6849 {
6850 char *codeset = nl_langinfo(CODESET);
Mark Dickinsonda2706b2008-12-11 18:03:03 +00006851 if (codeset != NULL && codeset[0] != 0)
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006852 return PyUnicode_FromString(codeset);
6853 }
6854#endif
6855 Py_INCREF(Py_None);
6856 return Py_None;
6857}
6858
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006859#ifdef __VMS
6860/* Use openssl random routine */
6861#include <openssl/rand.h>
6862PyDoc_STRVAR(vms_urandom__doc__,
6863"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006864Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006865
6866static PyObject*
6867vms_urandom(PyObject *self, PyObject *args)
6868{
6869 int howMany;
6870 PyObject* result;
6871
6872 /* Read arguments */
6873 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
6874 return NULL;
6875 if (howMany < 0)
6876 return PyErr_Format(PyExc_ValueError,
6877 "negative argument not allowed");
6878
6879 /* Allocate bytes */
Christian Heimes72b710a2008-05-26 13:28:38 +00006880 result = PyBytes_FromStringAndSize(NULL, howMany);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006881 if (result != NULL) {
6882 /* Get random data */
6883 if (RAND_pseudo_bytes((unsigned char*)
Christian Heimes72b710a2008-05-26 13:28:38 +00006884 PyBytes_AS_STRING(result),
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006885 howMany) < 0) {
6886 Py_DECREF(result);
6887 return PyErr_Format(PyExc_ValueError,
6888 "RAND_pseudo_bytes");
6889 }
6890 }
6891 return result;
6892}
6893#endif
6894
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006895static PyMethodDef posix_methods[] = {
6896 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6897#ifdef HAVE_TTYNAME
6898 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6899#endif
6900 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00006901#ifdef HAVE_CHFLAGS
6902 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
6903#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006904 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00006905#ifdef HAVE_FCHMOD
6906 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
6907#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006908#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006909 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006910#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00006911#ifdef HAVE_LCHMOD
6912 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
6913#endif /* HAVE_LCHMOD */
6914#ifdef HAVE_FCHOWN
6915 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
6916#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00006917#ifdef HAVE_LCHFLAGS
6918 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
6919#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006920#ifdef HAVE_LCHOWN
6921 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6922#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006923#ifdef HAVE_CHROOT
6924 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6925#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006926#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006927 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006928#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006929#ifdef HAVE_GETCWD
Guido van Rossumf0af3e32008-10-02 18:55:37 +00006930 {"getcwd", (PyCFunction)posix_getcwd_unicode,
6931 METH_NOARGS, posix_getcwd__doc__},
6932 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
6933 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006934#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006935#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006936 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006937#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006938 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6939 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6940 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006941#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006942 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006943#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006944#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006945 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006946#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006947 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6948 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6949 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006950 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006951#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006952 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006953#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006954#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006955 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006956#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006957 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006958#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00006959 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006960#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006961 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6962 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6963 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006964#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00006965 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006966#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006967 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006968#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006969 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6970 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006971#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006972#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006973 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6974 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006975#if defined(PYOS_OS2)
6976 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
6977 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
6978#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00006979#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006980#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00006981 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006982#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006983#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00006984 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006985#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006986#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00006987 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006988#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006989#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00006990 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00006991#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006992#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006993 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006994#endif /* HAVE_GETEGID */
6995#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006996 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006997#endif /* HAVE_GETEUID */
6998#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006999 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007000#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007001#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007002 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007003#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007004 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007005#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007006 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007007#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007008#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007009 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007010#endif /* HAVE_GETPPID */
7011#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007012 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007013#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007014#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007015 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007016#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007017#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007018 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007019#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007020#ifdef HAVE_KILLPG
7021 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7022#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007023#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007024 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007025#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007026#ifdef MS_WINDOWS
7027 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7028#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007029#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007030 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007031#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007032#ifdef HAVE_SETEUID
7033 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7034#endif /* HAVE_SETEUID */
7035#ifdef HAVE_SETEGID
7036 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7037#endif /* HAVE_SETEGID */
7038#ifdef HAVE_SETREUID
7039 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7040#endif /* HAVE_SETREUID */
7041#ifdef HAVE_SETREGID
7042 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7043#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007044#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007045 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007046#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007047#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00007048 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007049#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007050#ifdef HAVE_GETPGID
7051 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7052#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007053#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007054 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007055#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007056#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007057 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007058#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007059#ifdef HAVE_WAIT3
7060 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
7061#endif /* HAVE_WAIT3 */
7062#ifdef HAVE_WAIT4
7063 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
7064#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007065#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007066 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007067#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007068#ifdef HAVE_GETSID
7069 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7070#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007071#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007072 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007073#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007074#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007075 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007076#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007077#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007078 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007079#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007080#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007081 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007082#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007083 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7084 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Christian Heimesfdab48e2008-01-20 09:06:41 +00007085 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007086 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007087 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7088 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7089 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7090 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7091 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7092 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007093 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007094#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007095 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007096#endif
7097#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007098 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007099#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007100#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007101 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7102#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007103#ifdef HAVE_DEVICE_MACROS
7104 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7105 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7106 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7107#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007108#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007109 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007110#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007111#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007112 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007113#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007114#ifdef HAVE_UNSETENV
7115 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7116#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007117 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007118#ifdef HAVE_FCHDIR
7119 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7120#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007121#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007122 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007123#endif
7124#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007125 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007126#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007127#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007128#ifdef WCOREDUMP
7129 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7130#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007131#ifdef WIFCONTINUED
7132 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7133#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007134#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007135 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007136#endif /* WIFSTOPPED */
7137#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007138 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007139#endif /* WIFSIGNALED */
7140#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007141 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007142#endif /* WIFEXITED */
7143#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007144 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007145#endif /* WEXITSTATUS */
7146#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007147 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007148#endif /* WTERMSIG */
7149#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007150 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007151#endif /* WSTOPSIG */
7152#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007153#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007154 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007155#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007156#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007157 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007158#endif
Fred Drakec9680921999-12-13 16:37:25 +00007159#ifdef HAVE_CONFSTR
7160 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7161#endif
7162#ifdef HAVE_SYSCONF
7163 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7164#endif
7165#ifdef HAVE_FPATHCONF
7166 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7167#endif
7168#ifdef HAVE_PATHCONF
7169 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7170#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007171 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007172#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007173 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7174#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007175#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007176 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007177#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007178 #ifdef MS_WINDOWS
7179 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7180 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007181 #ifdef __VMS
7182 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
7183 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007184 {NULL, NULL} /* Sentinel */
7185};
7186
7187
Barry Warsaw4a342091996-12-19 23:50:02 +00007188static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007189ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007190{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007191 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007192}
7193
Guido van Rossumd48f2521997-12-05 22:19:34 +00007194#if defined(PYOS_OS2)
7195/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007196static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007197{
7198 APIRET rc;
7199 ULONG values[QSV_MAX+1];
7200 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007201 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007202
7203 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007204 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007205 Py_END_ALLOW_THREADS
7206
7207 if (rc != NO_ERROR) {
7208 os2_error(rc);
7209 return -1;
7210 }
7211
Fred Drake4d1e64b2002-04-15 19:40:07 +00007212 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7213 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7214 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7215 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7216 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7217 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7218 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007219
7220 switch (values[QSV_VERSION_MINOR]) {
7221 case 0: ver = "2.00"; break;
7222 case 10: ver = "2.10"; break;
7223 case 11: ver = "2.11"; break;
7224 case 30: ver = "3.00"; break;
7225 case 40: ver = "4.00"; break;
7226 case 50: ver = "5.00"; break;
7227 default:
Tim Peters885d4572001-11-28 20:27:42 +00007228 PyOS_snprintf(tmp, sizeof(tmp),
7229 "%d-%d", values[QSV_VERSION_MAJOR],
7230 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007231 ver = &tmp[0];
7232 }
7233
7234 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007235 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007236 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007237
7238 /* Add Indicator of Which Drive was Used to Boot the System */
7239 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7240 tmp[1] = ':';
7241 tmp[2] = '\0';
7242
Fred Drake4d1e64b2002-04-15 19:40:07 +00007243 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007244}
7245#endif
7246
Barry Warsaw4a342091996-12-19 23:50:02 +00007247static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007248all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007249{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007250#ifdef F_OK
7251 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007252#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007253#ifdef R_OK
7254 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007255#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007256#ifdef W_OK
7257 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007258#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007259#ifdef X_OK
7260 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007261#endif
Fred Drakec9680921999-12-13 16:37:25 +00007262#ifdef NGROUPS_MAX
7263 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7264#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007265#ifdef TMP_MAX
7266 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7267#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007268#ifdef WCONTINUED
7269 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7270#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007271#ifdef WNOHANG
7272 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007273#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007274#ifdef WUNTRACED
7275 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7276#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007277#ifdef O_RDONLY
7278 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7279#endif
7280#ifdef O_WRONLY
7281 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7282#endif
7283#ifdef O_RDWR
7284 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7285#endif
7286#ifdef O_NDELAY
7287 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7288#endif
7289#ifdef O_NONBLOCK
7290 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7291#endif
7292#ifdef O_APPEND
7293 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7294#endif
7295#ifdef O_DSYNC
7296 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7297#endif
7298#ifdef O_RSYNC
7299 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7300#endif
7301#ifdef O_SYNC
7302 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7303#endif
7304#ifdef O_NOCTTY
7305 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7306#endif
7307#ifdef O_CREAT
7308 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7309#endif
7310#ifdef O_EXCL
7311 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7312#endif
7313#ifdef O_TRUNC
7314 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7315#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007316#ifdef O_BINARY
7317 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7318#endif
7319#ifdef O_TEXT
7320 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7321#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007322#ifdef O_LARGEFILE
7323 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7324#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007325#ifdef O_SHLOCK
7326 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7327#endif
7328#ifdef O_EXLOCK
7329 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7330#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007331
Tim Peters5aa91602002-01-30 05:46:57 +00007332/* MS Windows */
7333#ifdef O_NOINHERIT
7334 /* Don't inherit in child processes. */
7335 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7336#endif
7337#ifdef _O_SHORT_LIVED
7338 /* Optimize for short life (keep in memory). */
7339 /* MS forgot to define this one with a non-underscore form too. */
7340 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7341#endif
7342#ifdef O_TEMPORARY
7343 /* Automatically delete when last handle is closed. */
7344 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7345#endif
7346#ifdef O_RANDOM
7347 /* Optimize for random access. */
7348 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7349#endif
7350#ifdef O_SEQUENTIAL
7351 /* Optimize for sequential access. */
7352 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7353#endif
7354
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007355/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00007356#ifdef O_ASYNC
7357 /* Send a SIGIO signal whenever input or output
7358 becomes available on file descriptor */
7359 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
7360#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007361#ifdef O_DIRECT
7362 /* Direct disk access. */
7363 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7364#endif
7365#ifdef O_DIRECTORY
7366 /* Must be a directory. */
7367 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7368#endif
7369#ifdef O_NOFOLLOW
7370 /* Do not follow links. */
7371 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7372#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00007373#ifdef O_NOATIME
7374 /* Do not update the access time. */
7375 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
7376#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007377
Barry Warsaw5676bd12003-01-07 20:57:09 +00007378 /* These come from sysexits.h */
7379#ifdef EX_OK
7380 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007381#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007382#ifdef EX_USAGE
7383 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007384#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007385#ifdef EX_DATAERR
7386 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007387#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007388#ifdef EX_NOINPUT
7389 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007390#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007391#ifdef EX_NOUSER
7392 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007393#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007394#ifdef EX_NOHOST
7395 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007396#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007397#ifdef EX_UNAVAILABLE
7398 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007399#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007400#ifdef EX_SOFTWARE
7401 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007402#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007403#ifdef EX_OSERR
7404 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007405#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007406#ifdef EX_OSFILE
7407 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007408#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007409#ifdef EX_CANTCREAT
7410 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007411#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007412#ifdef EX_IOERR
7413 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007414#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007415#ifdef EX_TEMPFAIL
7416 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007417#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007418#ifdef EX_PROTOCOL
7419 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007420#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007421#ifdef EX_NOPERM
7422 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007423#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007424#ifdef EX_CONFIG
7425 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007426#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007427#ifdef EX_NOTFOUND
7428 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007429#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007430
Guido van Rossum246bc171999-02-01 23:54:31 +00007431#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007432#if defined(PYOS_OS2) && defined(PYCC_GCC)
7433 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7434 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7435 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7436 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7437 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7438 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7439 if (ins(d, "P_PM", (long)P_PM)) return -1;
7440 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7441 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7442 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7443 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7444 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7445 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7446 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7447 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7448 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7449 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7450 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7451 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7452 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7453#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007454 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7455 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7456 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7457 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7458 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007459#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007460#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007461
Guido van Rossumd48f2521997-12-05 22:19:34 +00007462#if defined(PYOS_OS2)
7463 if (insertvalues(d)) return -1;
7464#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007465 return 0;
7466}
7467
7468
Tim Peters5aa91602002-01-30 05:46:57 +00007469#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007470#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007471#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007472
7473#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007474#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007475#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007476
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007477#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00007478#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007479#define MODNAME "posix"
7480#endif
7481
Martin v. Löwis1a214512008-06-11 05:26:20 +00007482static struct PyModuleDef posixmodule = {
7483 PyModuleDef_HEAD_INIT,
7484 MODNAME,
7485 posix__doc__,
7486 -1,
7487 posix_methods,
7488 NULL,
7489 NULL,
7490 NULL,
7491 NULL
7492};
7493
7494
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007495PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007496INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007497{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007498 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007499
Martin v. Löwis1a214512008-06-11 05:26:20 +00007500 m = PyModule_Create(&posixmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00007501 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007502 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007503
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007504 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007505 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007506 Py_XINCREF(v);
7507 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007508 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00007509 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007510
Fred Drake4d1e64b2002-04-15 19:40:07 +00007511 if (all_ins(m))
Martin v. Löwis1a214512008-06-11 05:26:20 +00007512 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00007513
Fred Drake4d1e64b2002-04-15 19:40:07 +00007514 if (setup_confname_tables(m))
Martin v. Löwis1a214512008-06-11 05:26:20 +00007515 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00007516
Fred Drake4d1e64b2002-04-15 19:40:07 +00007517 Py_INCREF(PyExc_OSError);
7518 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007519
Guido van Rossumb3d39562000-01-31 18:41:26 +00007520#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007521 if (posix_putenv_garbage == NULL)
7522 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007523#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007524
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007525 if (!initialized) {
7526 stat_result_desc.name = MODNAME ".stat_result";
7527 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7528 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7529 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7530 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7531 structseq_new = StatResultType.tp_new;
7532 StatResultType.tp_new = statresult_new;
7533
7534 statvfs_result_desc.name = MODNAME ".statvfs_result";
7535 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007536#ifdef NEED_TICKS_PER_SECOND
7537# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
7538 ticks_per_second = sysconf(_SC_CLK_TCK);
7539# elif defined(HZ)
7540 ticks_per_second = HZ;
7541# else
7542 ticks_per_second = 60; /* magic fallback value; may be bogus */
7543# endif
7544#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007545 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007546 Py_INCREF((PyObject*) &StatResultType);
7547 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007548 Py_INCREF((PyObject*) &StatVFSResultType);
7549 PyModule_AddObject(m, "statvfs_result",
7550 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007551 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007552
7553#ifdef __APPLE__
7554 /*
7555 * Step 2 of weak-linking support on Mac OS X.
7556 *
7557 * The code below removes functions that are not available on the
7558 * currently active platform.
7559 *
7560 * This block allow one to use a python binary that was build on
7561 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7562 * OSX 10.4.
7563 */
7564#ifdef HAVE_FSTATVFS
7565 if (fstatvfs == NULL) {
7566 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007567 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007568 }
7569 }
7570#endif /* HAVE_FSTATVFS */
7571
7572#ifdef HAVE_STATVFS
7573 if (statvfs == NULL) {
7574 if (PyObject_DelAttrString(m, "statvfs") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007575 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007576 }
7577 }
7578#endif /* HAVE_STATVFS */
7579
7580# ifdef HAVE_LCHOWN
7581 if (lchown == NULL) {
7582 if (PyObject_DelAttrString(m, "lchown") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007583 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007584 }
7585 }
7586#endif /* HAVE_LCHOWN */
7587
7588
7589#endif /* __APPLE__ */
Martin v. Löwis1a214512008-06-11 05:26:20 +00007590 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007591
Guido van Rossumb6775db1994-08-01 11:34:53 +00007592}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007593
7594#ifdef __cplusplus
7595}
7596#endif