blob: 0d873d1e53c800157ad5791f0140fbf502bcce10 [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;
385#endif /* _SAFECRT_IMPL */
386 } ioinfo;
387#endif
388
389extern __declspec(dllimport) ioinfo * __pioinfo[];
390#define IOINFO_L2E 5
391#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
392#define IOINFO_ARRAYS 64
393#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
394#define FOPEN 0x01
395#define _NO_CONSOLE_FILENO (intptr_t)-2
396
397/* This function emulates what the windows CRT does to validate file handles */
398int
399_PyVerify_fd(int fd)
400{
401 const int i1 = fd >> IOINFO_L2E;
402 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
403
404 /* See that it isn't a special CLEAR fileno */
405 if (fd != _NO_CONSOLE_FILENO) {
406 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
407 * we check pointer validity and other info
408 */
409 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
410 /* finally, check that the file is open */
411 if (__pioinfo[i1][i2].osfile & FOPEN)
412 return 1;
413 }
414 }
415 errno = EBADF;
416 return 0;
417}
418
419/* the special case of checking dup2. The target fd must be in a sensible range */
420static int
421_PyVerify_fd_dup2(int fd1, int fd2)
422{
423 if (!_PyVerify_fd(fd1))
424 return 0;
425 if (fd2 == _NO_CONSOLE_FILENO)
426 return 0;
427 if ((unsigned)fd2 < _NHANDLE_)
428 return 1;
429 else
430 return 0;
431}
432#else
433/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
434#define _PyVerify_fd_dup2(A, B) (1)
435#endif
436
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000437/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000438#ifdef WITH_NEXT_FRAMEWORK
439/* On Darwin/MacOSX a shared library or framework has no access to
440** environ directly, we must obtain it with _NSGetEnviron().
441*/
442#include <crt_externs.h>
443static char **environ;
444#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000445extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000446#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000447
Barry Warsaw53699e91996-12-10 23:23:01 +0000448static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000449convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000450{
Barry Warsaw53699e91996-12-10 23:23:01 +0000451 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000452#ifdef MS_WINDOWS
453 wchar_t **e;
454#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000455 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000456#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000457 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000458 if (d == NULL)
459 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000460#ifdef WITH_NEXT_FRAMEWORK
461 if (environ == NULL)
462 environ = *_NSGetEnviron();
463#endif
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000464#ifdef MS_WINDOWS
465 /* _wenviron must be initialized in this way if the program is started
466 through main() instead of wmain(). */
467 _wgetenv(L"");
468 if (_wenviron == NULL)
469 return d;
470 /* This part ignores errors */
471 for (e = _wenviron; *e != NULL; e++) {
472 PyObject *k;
473 PyObject *v;
474 wchar_t *p = wcschr(*e, L'=');
475 if (p == NULL)
476 continue;
477 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
478 if (k == NULL) {
479 PyErr_Clear();
480 continue;
481 }
482 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
483 if (v == NULL) {
484 PyErr_Clear();
485 Py_DECREF(k);
486 continue;
487 }
488 if (PyDict_GetItem(d, k) == NULL) {
489 if (PyDict_SetItem(d, k, v) != 0)
490 PyErr_Clear();
491 }
492 Py_DECREF(k);
493 Py_DECREF(v);
494 }
495#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000496 if (environ == NULL)
497 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000498 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000499 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000500 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000501 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502 char *p = strchr(*e, '=');
503 if (p == NULL)
504 continue;
Guido van Rossum98297ee2007-11-06 21:34:58 +0000505 k = PyUnicode_FromStringAndSize(*e, (int)(p-*e));
Guido van Rossum6a619f41999-08-03 19:41:10 +0000506 if (k == NULL) {
507 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000508 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000509 }
Guido van Rossum98297ee2007-11-06 21:34:58 +0000510 v = PyUnicode_FromString(p+1);
Guido van Rossum6a619f41999-08-03 19:41:10 +0000511 if (v == NULL) {
512 PyErr_Clear();
513 Py_DECREF(k);
514 continue;
515 }
516 if (PyDict_GetItem(d, k) == NULL) {
517 if (PyDict_SetItem(d, k, v) != 0)
518 PyErr_Clear();
519 }
520 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000521 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000522 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000523#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000524#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000525 {
526 APIRET rc;
527 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
528
529 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000530 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Christian Heimes72b710a2008-05-26 13:28:38 +0000531 PyObject *v = PyBytes_FromString(buffer);
Neal Norwitz93c56822007-08-26 07:10:06 +0000532 PyDict_SetItemString(d, "BEGINLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000533 Py_DECREF(v);
534 }
535 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
536 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_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, "ENDLIBPATH", v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000539 Py_DECREF(v);
540 }
541 }
542#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000543 return d;
544}
545
546
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000547/* Set a POSIX-specific error from errno, and return NULL */
548
Barry Warsawd58d7641998-07-23 16:14:40 +0000549static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000550posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000551{
Barry Warsawca74da41999-02-09 19:31:45 +0000552 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000553}
Barry Warsawd58d7641998-07-23 16:14:40 +0000554static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000555posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000556{
Barry Warsawca74da41999-02-09 19:31:45 +0000557 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000558}
559
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000560#ifdef Py_WIN_WIDE_FILENAMES
561static PyObject *
562posix_error_with_unicode_filename(Py_UNICODE* name)
563{
564 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
565}
566#endif /* Py_WIN_WIDE_FILENAMES */
567
568
Mark Hammondef8b6542001-05-13 08:04:26 +0000569static PyObject *
570posix_error_with_allocated_filename(char* name)
571{
572 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
573 PyMem_Free(name);
574 return rc;
575}
576
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000577#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000578static PyObject *
579win32_error(char* function, char* filename)
580{
Mark Hammond33a6da92000-08-15 00:46:38 +0000581 /* XXX We should pass the function name along in the future.
Georg Brandl38feaf02008-05-25 07:45:51 +0000582 (winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000583 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000584 Windows error object, which is non-trivial.
585 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000586 errno = GetLastError();
587 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000588 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000589 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000590 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000591}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000592
593#ifdef Py_WIN_WIDE_FILENAMES
594static PyObject *
595win32_error_unicode(char* function, Py_UNICODE* filename)
596{
597 /* XXX - see win32_error for comments on 'function' */
598 errno = GetLastError();
599 if (filename)
600 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
601 else
602 return PyErr_SetFromWindowsErr(errno);
603}
604
Thomas Wouters477c8d52006-05-27 19:21:47 +0000605static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000606convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000607{
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000608 if (PyUnicode_CheckExact(*param))
609 Py_INCREF(*param);
610 else if (PyUnicode_Check(*param))
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000611 /* For a Unicode subtype that's not a Unicode object,
612 return a true Unicode object with the same data. */
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000613 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
614 PyUnicode_GET_SIZE(*param));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000615 else
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000616 *param = PyUnicode_FromEncodedObject(*param,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000617 Py_FileSystemDefaultEncoding,
618 "strict");
619 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000620}
621
622#endif /* Py_WIN_WIDE_FILENAMES */
623
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000624#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000625
Guido van Rossumd48f2521997-12-05 22:19:34 +0000626#if defined(PYOS_OS2)
627/**********************************************************************
628 * Helper Function to Trim and Format OS/2 Messages
629 **********************************************************************/
630 static void
631os2_formatmsg(char *msgbuf, int msglen, char *reason)
632{
633 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
634
635 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
636 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
637
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000638 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000639 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
640 }
641
642 /* Add Optional Reason Text */
643 if (reason) {
644 strcat(msgbuf, " : ");
645 strcat(msgbuf, reason);
646 }
647}
648
649/**********************************************************************
650 * Decode an OS/2 Operating System Error Code
651 *
652 * A convenience function to lookup an OS/2 error code and return a
653 * text message we can use to raise a Python exception.
654 *
655 * Notes:
656 * The messages for errors returned from the OS/2 kernel reside in
657 * the file OSO001.MSG in the \OS2 directory hierarchy.
658 *
659 **********************************************************************/
660 static char *
661os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
662{
663 APIRET rc;
664 ULONG msglen;
665
666 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
667 Py_BEGIN_ALLOW_THREADS
668 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
669 errorcode, "oso001.msg", &msglen);
670 Py_END_ALLOW_THREADS
671
672 if (rc == NO_ERROR)
673 os2_formatmsg(msgbuf, msglen, reason);
674 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000675 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000676 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000677
678 return msgbuf;
679}
680
681/* Set an OS/2-specific error and return NULL. OS/2 kernel
682 errors are not in a global variable e.g. 'errno' nor are
683 they congruent with posix error numbers. */
684
685static PyObject * os2_error(int code)
686{
687 char text[1024];
688 PyObject *v;
689
690 os2_strerror(text, sizeof(text), code, "");
691
692 v = Py_BuildValue("(is)", code, text);
693 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000694 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000695 Py_DECREF(v);
696 }
697 return NULL; /* Signal to Python that an Exception is Pending */
698}
699
700#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000701
702/* POSIX generic methods */
703
Barry Warsaw53699e91996-12-10 23:23:01 +0000704static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000705posix_fildes(PyObject *fdobj, int (*func)(int))
706{
707 int fd;
708 int res;
709 fd = PyObject_AsFileDescriptor(fdobj);
710 if (fd < 0)
711 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000712 if (!_PyVerify_fd(fd))
713 return posix_error();
Fred Drake4d1e64b2002-04-15 19:40:07 +0000714 Py_BEGIN_ALLOW_THREADS
715 res = (*func)(fd);
716 Py_END_ALLOW_THREADS
717 if (res < 0)
718 return posix_error();
719 Py_INCREF(Py_None);
720 return Py_None;
721}
Guido van Rossum21142a01999-01-08 21:05:37 +0000722
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000723#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000724static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000725unicode_file_names(void)
726{
727 static int canusewide = -1;
728 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000729 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000730 the Windows NT family. */
731 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
732 }
733 return canusewide;
734}
735#endif
Tim Peters11b23062003-04-23 02:39:17 +0000736
Guido van Rossum21142a01999-01-08 21:05:37 +0000737static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000738posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000739{
Mark Hammondef8b6542001-05-13 08:04:26 +0000740 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000741 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000742 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000743 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000744 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000745 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000746 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000747 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000748 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000749 return posix_error_with_allocated_filename(path1);
750 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000751 Py_INCREF(Py_None);
752 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000753}
754
Barry Warsaw53699e91996-12-10 23:23:01 +0000755static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000756posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000757 char *format,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000758 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000759{
Mark Hammondef8b6542001-05-13 08:04:26 +0000760 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000761 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000762 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000763 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000764 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000765 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000766 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000767 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000768 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000769 PyMem_Free(path1);
770 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000771 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000772 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000773 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000774 Py_INCREF(Py_None);
775 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000776}
777
Thomas Wouters477c8d52006-05-27 19:21:47 +0000778#ifdef Py_WIN_WIDE_FILENAMES
779static PyObject*
780win32_1str(PyObject* args, char* func,
781 char* format, BOOL (__stdcall *funcA)(LPCSTR),
782 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
783{
784 PyObject *uni;
785 char *ansi;
786 BOOL result;
787 if (unicode_file_names()) {
788 if (!PyArg_ParseTuple(args, wformat, &uni))
789 PyErr_Clear();
790 else {
791 Py_BEGIN_ALLOW_THREADS
792 result = funcW(PyUnicode_AsUnicode(uni));
793 Py_END_ALLOW_THREADS
794 if (!result)
795 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
796 Py_INCREF(Py_None);
797 return Py_None;
798 }
799 }
800 if (!PyArg_ParseTuple(args, format, &ansi))
801 return NULL;
802 Py_BEGIN_ALLOW_THREADS
803 result = funcA(ansi);
804 Py_END_ALLOW_THREADS
805 if (!result)
806 return win32_error(func, ansi);
807 Py_INCREF(Py_None);
808 return Py_None;
809
810}
811
812/* This is a reimplementation of the C library's chdir function,
813 but one that produces Win32 errors instead of DOS error codes.
814 chdir is essentially a wrapper around SetCurrentDirectory; however,
815 it also needs to set "magic" environment variables indicating
816 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000817static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000818win32_chdir(LPCSTR path)
819{
820 char new_path[MAX_PATH+1];
821 int result;
822 char env[4] = "=x:";
823
824 if(!SetCurrentDirectoryA(path))
825 return FALSE;
826 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
827 if (!result)
828 return FALSE;
829 /* In the ANSI API, there should not be any paths longer
830 than MAX_PATH. */
831 assert(result <= MAX_PATH+1);
832 if (strncmp(new_path, "\\\\", 2) == 0 ||
833 strncmp(new_path, "//", 2) == 0)
834 /* UNC path, nothing to do. */
835 return TRUE;
836 env[1] = new_path[0];
837 return SetEnvironmentVariableA(env, new_path);
838}
839
840/* The Unicode version differs from the ANSI version
841 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000842static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000843win32_wchdir(LPCWSTR path)
844{
845 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
846 int result;
847 wchar_t env[4] = L"=x:";
848
849 if(!SetCurrentDirectoryW(path))
850 return FALSE;
851 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
852 if (!result)
853 return FALSE;
854 if (result > MAX_PATH+1) {
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000855 new_path = malloc(result * sizeof(wchar_t));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000856 if (!new_path) {
857 SetLastError(ERROR_OUTOFMEMORY);
858 return FALSE;
859 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000860 result = GetCurrentDirectoryW(result, new_path);
861 if (!result) {
862 free(new_path);
863 return FALSE;
864 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000865 }
866 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
867 wcsncmp(new_path, L"//", 2) == 0)
868 /* UNC path, nothing to do. */
869 return TRUE;
870 env[1] = new_path[0];
871 result = SetEnvironmentVariableW(env, new_path);
872 if (new_path != _new_path)
873 free(new_path);
874 return result;
875}
876#endif
877
Martin v. Löwis14694662006-02-03 12:54:16 +0000878#ifdef MS_WINDOWS
879/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
880 - time stamps are restricted to second resolution
881 - file modification times suffer from forth-and-back conversions between
882 UTC and local time
883 Therefore, we implement our own stat, based on the Win32 API directly.
884*/
885#define HAVE_STAT_NSEC 1
886
887struct win32_stat{
888 int st_dev;
889 __int64 st_ino;
890 unsigned short st_mode;
891 int st_nlink;
892 int st_uid;
893 int st_gid;
894 int st_rdev;
895 __int64 st_size;
896 int st_atime;
897 int st_atime_nsec;
898 int st_mtime;
899 int st_mtime_nsec;
900 int st_ctime;
901 int st_ctime_nsec;
902};
903
904static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
905
906static void
907FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
908{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000909 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
910 /* Cannot simply cast and dereference in_ptr,
911 since it might not be aligned properly */
912 __int64 in;
913 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000914 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
915 /* XXX Win32 supports time stamps past 2038; we currently don't */
916 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
917}
918
Thomas Wouters477c8d52006-05-27 19:21:47 +0000919static void
920time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
921{
922 /* XXX endianness */
923 __int64 out;
924 out = time_in + secs_between_epochs;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000925 out = out * 10000000 + nsec_in / 100;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000926 memcpy(out_ptr, &out, sizeof(out));
927}
928
Martin v. Löwis14694662006-02-03 12:54:16 +0000929/* Below, we *know* that ugo+r is 0444 */
930#if _S_IREAD != 0400
931#error Unsupported C library
932#endif
933static int
934attributes_to_mode(DWORD attr)
935{
936 int m = 0;
937 if (attr & FILE_ATTRIBUTE_DIRECTORY)
938 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
939 else
940 m |= _S_IFREG;
941 if (attr & FILE_ATTRIBUTE_READONLY)
942 m |= 0444;
943 else
944 m |= 0666;
945 return m;
946}
947
948static int
949attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
950{
951 memset(result, 0, sizeof(*result));
952 result->st_mode = attributes_to_mode(info->dwFileAttributes);
953 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
954 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
955 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
956 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
957
958 return 0;
959}
960
Thomas Wouters89f507f2006-12-13 04:49:30 +0000961/* Emulate GetFileAttributesEx[AW] on Windows 95 */
962static int checked = 0;
963static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
964static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
965static void
966check_gfax()
967{
968 HINSTANCE hKernel32;
969 if (checked)
970 return;
971 checked = 1;
972 hKernel32 = GetModuleHandle("KERNEL32");
973 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
974 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
975}
976
Guido van Rossumd8faa362007-04-27 19:54:29 +0000977static BOOL
978attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
979{
980 HANDLE hFindFile;
981 WIN32_FIND_DATAA FileData;
982 hFindFile = FindFirstFileA(pszFile, &FileData);
983 if (hFindFile == INVALID_HANDLE_VALUE)
984 return FALSE;
985 FindClose(hFindFile);
986 pfad->dwFileAttributes = FileData.dwFileAttributes;
987 pfad->ftCreationTime = FileData.ftCreationTime;
988 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
989 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
990 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
991 pfad->nFileSizeLow = FileData.nFileSizeLow;
992 return TRUE;
993}
994
995static BOOL
996attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
997{
998 HANDLE hFindFile;
999 WIN32_FIND_DATAW FileData;
1000 hFindFile = FindFirstFileW(pszFile, &FileData);
1001 if (hFindFile == INVALID_HANDLE_VALUE)
1002 return FALSE;
1003 FindClose(hFindFile);
1004 pfad->dwFileAttributes = FileData.dwFileAttributes;
1005 pfad->ftCreationTime = FileData.ftCreationTime;
1006 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1007 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1008 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1009 pfad->nFileSizeLow = FileData.nFileSizeLow;
1010 return TRUE;
1011}
1012
Thomas Wouters89f507f2006-12-13 04:49:30 +00001013static BOOL WINAPI
1014Py_GetFileAttributesExA(LPCSTR pszFile,
1015 GET_FILEEX_INFO_LEVELS level,
1016 LPVOID pv)
1017{
1018 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00001019 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1020 /* First try to use the system's implementation, if that is
1021 available and either succeeds to gives an error other than
1022 that it isn't implemented. */
1023 check_gfax();
1024 if (gfaxa) {
1025 result = gfaxa(pszFile, level, pv);
1026 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1027 return result;
1028 }
1029 /* It's either not present, or not implemented.
1030 Emulate using FindFirstFile. */
1031 if (level != GetFileExInfoStandard) {
1032 SetLastError(ERROR_INVALID_PARAMETER);
1033 return FALSE;
1034 }
1035 /* Use GetFileAttributes to validate that the file name
1036 does not contain wildcards (which FindFirstFile would
1037 accept). */
1038 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
1039 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001040 return attributes_from_dir(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001041}
1042
1043static BOOL WINAPI
1044Py_GetFileAttributesExW(LPCWSTR pszFile,
1045 GET_FILEEX_INFO_LEVELS level,
1046 LPVOID pv)
1047{
1048 BOOL result;
Thomas Wouters89f507f2006-12-13 04:49:30 +00001049 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1050 /* First try to use the system's implementation, if that is
1051 available and either succeeds to gives an error other than
1052 that it isn't implemented. */
1053 check_gfax();
1054 if (gfaxa) {
1055 result = gfaxw(pszFile, level, pv);
1056 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1057 return result;
1058 }
1059 /* It's either not present, or not implemented.
1060 Emulate using FindFirstFile. */
1061 if (level != GetFileExInfoStandard) {
1062 SetLastError(ERROR_INVALID_PARAMETER);
1063 return FALSE;
1064 }
1065 /* Use GetFileAttributes to validate that the file name
1066 does not contain wildcards (which FindFirstFile would
1067 accept). */
1068 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1069 return FALSE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001070 return attributes_from_dir_w(pszFile, pfad);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001071}
1072
Martin v. Löwis14694662006-02-03 12:54:16 +00001073static int
1074win32_stat(const char* path, struct win32_stat *result)
1075{
1076 WIN32_FILE_ATTRIBUTE_DATA info;
1077 int code;
1078 char *dot;
1079 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001080 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001081 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1082 /* Protocol violation: we explicitly clear errno, instead of
1083 setting it to a POSIX error. Callers should use GetLastError. */
1084 errno = 0;
1085 return -1;
1086 } else {
1087 /* Could not get attributes on open file. Fall back to
1088 reading the directory. */
1089 if (!attributes_from_dir(path, &info)) {
1090 /* Very strange. This should not fail now */
1091 errno = 0;
1092 return -1;
1093 }
1094 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001095 }
1096 code = attribute_data_to_stat(&info, result);
1097 if (code != 0)
1098 return code;
1099 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1100 dot = strrchr(path, '.');
1101 if (dot) {
1102 if (stricmp(dot, ".bat") == 0 ||
1103 stricmp(dot, ".cmd") == 0 ||
1104 stricmp(dot, ".exe") == 0 ||
1105 stricmp(dot, ".com") == 0)
1106 result->st_mode |= 0111;
1107 }
1108 return code;
1109}
1110
1111static int
1112win32_wstat(const wchar_t* path, struct win32_stat *result)
1113{
1114 int code;
1115 const wchar_t *dot;
1116 WIN32_FILE_ATTRIBUTE_DATA info;
1117 /* XXX not supported on Win95 and NT 3.x */
Thomas Wouters89f507f2006-12-13 04:49:30 +00001118 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
Guido van Rossumd8faa362007-04-27 19:54:29 +00001119 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1120 /* Protocol violation: we explicitly clear errno, instead of
1121 setting it to a POSIX error. Callers should use GetLastError. */
1122 errno = 0;
1123 return -1;
1124 } else {
1125 /* Could not get attributes on open file. Fall back to
1126 reading the directory. */
1127 if (!attributes_from_dir_w(path, &info)) {
1128 /* Very strange. This should not fail now */
1129 errno = 0;
1130 return -1;
1131 }
1132 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001133 }
1134 code = attribute_data_to_stat(&info, result);
1135 if (code < 0)
1136 return code;
1137 /* Set IFEXEC if it is an .exe, .bat, ... */
1138 dot = wcsrchr(path, '.');
1139 if (dot) {
1140 if (_wcsicmp(dot, L".bat") == 0 ||
1141 _wcsicmp(dot, L".cmd") == 0 ||
1142 _wcsicmp(dot, L".exe") == 0 ||
1143 _wcsicmp(dot, L".com") == 0)
1144 result->st_mode |= 0111;
1145 }
1146 return code;
1147}
1148
1149static int
1150win32_fstat(int file_number, struct win32_stat *result)
1151{
1152 BY_HANDLE_FILE_INFORMATION info;
1153 HANDLE h;
1154 int type;
1155
1156 h = (HANDLE)_get_osfhandle(file_number);
1157
1158 /* Protocol violation: we explicitly clear errno, instead of
1159 setting it to a POSIX error. Callers should use GetLastError. */
1160 errno = 0;
1161
1162 if (h == INVALID_HANDLE_VALUE) {
1163 /* This is really a C library error (invalid file handle).
1164 We set the Win32 error to the closes one matching. */
1165 SetLastError(ERROR_INVALID_HANDLE);
1166 return -1;
1167 }
1168 memset(result, 0, sizeof(*result));
1169
1170 type = GetFileType(h);
1171 if (type == FILE_TYPE_UNKNOWN) {
1172 DWORD error = GetLastError();
1173 if (error != 0) {
1174 return -1;
1175 }
1176 /* else: valid but unknown file */
1177 }
1178
1179 if (type != FILE_TYPE_DISK) {
1180 if (type == FILE_TYPE_CHAR)
1181 result->st_mode = _S_IFCHR;
1182 else if (type == FILE_TYPE_PIPE)
1183 result->st_mode = _S_IFIFO;
1184 return 0;
1185 }
1186
1187 if (!GetFileInformationByHandle(h, &info)) {
1188 return -1;
1189 }
1190
1191 /* similar to stat() */
1192 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1193 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1194 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1195 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1196 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1197 /* specific to fstat() */
1198 result->st_nlink = info.nNumberOfLinks;
1199 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1200 return 0;
1201}
1202
1203#endif /* MS_WINDOWS */
1204
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001205PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001206"stat_result: Result from stat or lstat.\n\n\
1207This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001208 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001209or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1210\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001211Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1212or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001213\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001214See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001215
1216static PyStructSequence_Field stat_result_fields[] = {
1217 {"st_mode", "protection bits"},
1218 {"st_ino", "inode"},
1219 {"st_dev", "device"},
1220 {"st_nlink", "number of hard links"},
1221 {"st_uid", "user ID of owner"},
1222 {"st_gid", "group ID of owner"},
1223 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001224 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1225 {NULL, "integer time of last access"},
1226 {NULL, "integer time of last modification"},
1227 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001228 {"st_atime", "time of last access"},
1229 {"st_mtime", "time of last modification"},
1230 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001231#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001232 {"st_blksize", "blocksize for filesystem I/O"},
1233#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001234#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001235 {"st_blocks", "number of blocks allocated"},
1236#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001237#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001238 {"st_rdev", "device type (if inode device)"},
1239#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001240#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1241 {"st_flags", "user defined flags for file"},
1242#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001243#ifdef HAVE_STRUCT_STAT_ST_GEN
1244 {"st_gen", "generation number"},
1245#endif
1246#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1247 {"st_birthtime", "time of creation"},
1248#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001249 {0}
1250};
1251
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001252#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001253#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001254#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001255#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001256#endif
1257
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001258#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001259#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1260#else
1261#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1262#endif
1263
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001264#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001265#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1266#else
1267#define ST_RDEV_IDX ST_BLOCKS_IDX
1268#endif
1269
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001270#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1271#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1272#else
1273#define ST_FLAGS_IDX ST_RDEV_IDX
1274#endif
1275
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001276#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001277#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001278#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001279#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001280#endif
1281
1282#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1283#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1284#else
1285#define ST_BIRTHTIME_IDX ST_GEN_IDX
1286#endif
1287
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001288static PyStructSequence_Desc stat_result_desc = {
1289 "stat_result", /* name */
1290 stat_result__doc__, /* doc */
1291 stat_result_fields,
1292 10
1293};
1294
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001295PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001296"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1297This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001298 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001299or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001300\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001301See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001302
1303static PyStructSequence_Field statvfs_result_fields[] = {
1304 {"f_bsize", },
1305 {"f_frsize", },
1306 {"f_blocks", },
1307 {"f_bfree", },
1308 {"f_bavail", },
1309 {"f_files", },
1310 {"f_ffree", },
1311 {"f_favail", },
1312 {"f_flag", },
1313 {"f_namemax",},
1314 {0}
1315};
1316
1317static PyStructSequence_Desc statvfs_result_desc = {
1318 "statvfs_result", /* name */
1319 statvfs_result__doc__, /* doc */
1320 statvfs_result_fields,
1321 10
1322};
1323
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001324static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001325static PyTypeObject StatResultType;
1326static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001327static newfunc structseq_new;
1328
1329static PyObject *
1330statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1331{
1332 PyStructSequence *result;
1333 int i;
1334
1335 result = (PyStructSequence*)structseq_new(type, args, kwds);
1336 if (!result)
1337 return NULL;
1338 /* If we have been initialized from a tuple,
1339 st_?time might be set to None. Initialize it
1340 from the int slots. */
1341 for (i = 7; i <= 9; i++) {
1342 if (result->ob_item[i+3] == Py_None) {
1343 Py_DECREF(Py_None);
1344 Py_INCREF(result->ob_item[i]);
1345 result->ob_item[i+3] = result->ob_item[i];
1346 }
1347 }
1348 return (PyObject*)result;
1349}
1350
1351
1352
1353/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001354static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001355
1356PyDoc_STRVAR(stat_float_times__doc__,
1357"stat_float_times([newval]) -> oldval\n\n\
1358Determine whether os.[lf]stat represents time stamps as float objects.\n\
1359If newval is True, future calls to stat() return floats, if it is False,\n\
1360future calls return ints. \n\
1361If newval is omitted, return the current setting.\n");
1362
1363static PyObject*
1364stat_float_times(PyObject* self, PyObject *args)
1365{
1366 int newval = -1;
1367 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1368 return NULL;
1369 if (newval == -1)
1370 /* Return old value */
1371 return PyBool_FromLong(_stat_float_times);
1372 _stat_float_times = newval;
1373 Py_INCREF(Py_None);
1374 return Py_None;
1375}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001376
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001377static void
1378fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1379{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001380 PyObject *fval,*ival;
1381#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001382 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001383#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001384 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001385#endif
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001386 if (!ival)
1387 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001388 if (_stat_float_times) {
1389 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1390 } else {
1391 fval = ival;
1392 Py_INCREF(fval);
1393 }
1394 PyStructSequence_SET_ITEM(v, index, ival);
1395 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001396}
1397
Tim Peters5aa91602002-01-30 05:46:57 +00001398/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001399 (used by posix_stat() and posix_fstat()) */
1400static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001401_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001402{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001403 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001404 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001405 if (v == NULL)
1406 return NULL;
1407
Christian Heimes217cfd12007-12-02 14:31:20 +00001408 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001409#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001410 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001411 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001412#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001413 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001414#endif
1415#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001416 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001417 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001418#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001419 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001420#endif
Christian Heimes217cfd12007-12-02 14:31:20 +00001421 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1422 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1423 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001424#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001425 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001426 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001427#else
Christian Heimes217cfd12007-12-02 14:31:20 +00001428 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001429#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001430
Martin v. Löwis14694662006-02-03 12:54:16 +00001431#if defined(HAVE_STAT_TV_NSEC)
1432 ansec = st->st_atim.tv_nsec;
1433 mnsec = st->st_mtim.tv_nsec;
1434 cnsec = st->st_ctim.tv_nsec;
1435#elif defined(HAVE_STAT_TV_NSEC2)
1436 ansec = st->st_atimespec.tv_nsec;
1437 mnsec = st->st_mtimespec.tv_nsec;
1438 cnsec = st->st_ctimespec.tv_nsec;
1439#elif defined(HAVE_STAT_NSEC)
1440 ansec = st->st_atime_nsec;
1441 mnsec = st->st_mtime_nsec;
1442 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001443#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001444 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001445#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001446 fill_time(v, 7, st->st_atime, ansec);
1447 fill_time(v, 8, st->st_mtime, mnsec);
1448 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001449
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001450#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001451 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001452 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001453#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001454#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001455 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001456 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001457#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001458#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001459 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001460 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001461#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001462#ifdef HAVE_STRUCT_STAT_ST_GEN
1463 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001464 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001465#endif
1466#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1467 {
1468 PyObject *val;
1469 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001470 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001471#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001472 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001473#else
1474 bnsec = 0;
1475#endif
1476 if (_stat_float_times) {
1477 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1478 } else {
Christian Heimes217cfd12007-12-02 14:31:20 +00001479 val = PyLong_FromLong((long)bsec);
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001480 }
1481 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1482 val);
1483 }
1484#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001485#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1486 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Christian Heimes217cfd12007-12-02 14:31:20 +00001487 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001488#endif
Fred Drake699f3522000-06-29 21:12:41 +00001489
1490 if (PyErr_Occurred()) {
1491 Py_DECREF(v);
1492 return NULL;
1493 }
1494
1495 return v;
1496}
1497
Martin v. Löwisd8948722004-06-02 09:57:56 +00001498#ifdef MS_WINDOWS
1499
1500/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1501 where / can be used in place of \ and the trailing slash is optional.
1502 Both SERVER and SHARE must have at least one character.
1503*/
1504
1505#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1506#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001507#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001508#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001509#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001510
Tim Peters4ad82172004-08-30 17:02:04 +00001511static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001512IsUNCRootA(char *path, int pathlen)
1513{
1514 #define ISSLASH ISSLASHA
1515
1516 int i, share;
1517
1518 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1519 /* minimum UNCRoot is \\x\y */
1520 return FALSE;
1521 for (i = 2; i < pathlen ; i++)
1522 if (ISSLASH(path[i])) break;
1523 if (i == 2 || i == pathlen)
1524 /* do not allow \\\SHARE or \\SERVER */
1525 return FALSE;
1526 share = i+1;
1527 for (i = share; i < pathlen; i++)
1528 if (ISSLASH(path[i])) break;
1529 return (i != share && (i == pathlen || i == pathlen-1));
1530
1531 #undef ISSLASH
1532}
1533
1534#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001535static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001536IsUNCRootW(Py_UNICODE *path, int pathlen)
1537{
1538 #define ISSLASH ISSLASHW
1539
1540 int i, share;
1541
1542 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1543 /* minimum UNCRoot is \\x\y */
1544 return FALSE;
1545 for (i = 2; i < pathlen ; i++)
1546 if (ISSLASH(path[i])) break;
1547 if (i == 2 || i == pathlen)
1548 /* do not allow \\\SHARE or \\SERVER */
1549 return FALSE;
1550 share = i+1;
1551 for (i = share; i < pathlen; i++)
1552 if (ISSLASH(path[i])) break;
1553 return (i != share && (i == pathlen || i == pathlen-1));
1554
1555 #undef ISSLASH
1556}
1557#endif /* Py_WIN_WIDE_FILENAMES */
1558#endif /* MS_WINDOWS */
1559
Barry Warsaw53699e91996-12-10 23:23:01 +00001560static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001561posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001562 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001563#ifdef __VMS
1564 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1565#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001566 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001567#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001568 char *wformat,
1569 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001570{
Fred Drake699f3522000-06-29 21:12:41 +00001571 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001572 char *path = NULL; /* pass this to stat; do not free() it */
1573 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001574 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001575 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001576
1577#ifdef Py_WIN_WIDE_FILENAMES
1578 /* If on wide-character-capable OS see if argument
1579 is Unicode and if so use wide API. */
1580 if (unicode_file_names()) {
1581 PyUnicodeObject *po;
1582 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001583 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1584
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001585 Py_BEGIN_ALLOW_THREADS
1586 /* PyUnicode_AS_UNICODE result OK without
1587 thread lock as it is a simple dereference. */
1588 res = wstatfunc(wpath, &st);
1589 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001590
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001591 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001592 return win32_error_unicode("stat", wpath);
1593 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001594 }
1595 /* Drop the argument parsing error as narrow strings
1596 are also valid. */
1597 PyErr_Clear();
1598 }
1599#endif
1600
Tim Peters5aa91602002-01-30 05:46:57 +00001601 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001602 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001603 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001604 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001605
Barry Warsaw53699e91996-12-10 23:23:01 +00001606 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001607 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001608 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001609
1610 if (res != 0) {
1611#ifdef MS_WINDOWS
1612 result = win32_error("stat", pathfree);
1613#else
1614 result = posix_error_with_filename(pathfree);
1615#endif
1616 }
1617 else
1618 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001619
Tim Peters500bd032001-12-19 19:05:01 +00001620 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001621 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001622}
1623
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001624/* POSIX methods */
1625
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001626PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001627"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001628Use the real uid/gid to test for access to a path. Note that most\n\
1629operations will use the effective uid/gid, therefore this routine can\n\
1630be used in a suid/sgid environment to test if the invoking user has the\n\
1631specified access to the path. The mode argument can be F_OK to test\n\
1632existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001633
1634static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001635posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001636{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001637 char *path;
1638 int mode;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001639
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001640#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001641 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001642 if (unicode_file_names()) {
1643 PyUnicodeObject *po;
1644 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1645 Py_BEGIN_ALLOW_THREADS
1646 /* PyUnicode_AS_UNICODE OK without thread lock as
1647 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001648 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001649 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001650 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001651 }
1652 /* Drop the argument parsing error as narrow strings
1653 are also valid. */
1654 PyErr_Clear();
1655 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001656 if (!PyArg_ParseTuple(args, "eti:access",
1657 Py_FileSystemDefaultEncoding, &path, &mode))
1658 return 0;
1659 Py_BEGIN_ALLOW_THREADS
1660 attr = GetFileAttributesA(path);
1661 Py_END_ALLOW_THREADS
1662 PyMem_Free(path);
1663finish:
1664 if (attr == 0xFFFFFFFF)
1665 /* File does not exist, or cannot read attributes */
1666 return PyBool_FromLong(0);
1667 /* Access is possible if either write access wasn't requested, or
Guido van Rossumb00324f2007-12-04 01:13:14 +00001668 the file isn't read-only, or if it's a directory, as there are
1669 no read-only directories on Windows. */
1670 return PyBool_FromLong(!(mode & 2)
1671 || !(attr & FILE_ATTRIBUTE_READONLY)
1672 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001673#else
1674 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001675 if (!PyArg_ParseTuple(args, "eti:access",
1676 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001677 return NULL;
1678 Py_BEGIN_ALLOW_THREADS
1679 res = access(path, mode);
1680 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001681 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001682 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001683#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001684}
1685
Guido van Rossumd371ff11999-01-25 16:12:23 +00001686#ifndef F_OK
1687#define F_OK 0
1688#endif
1689#ifndef R_OK
1690#define R_OK 4
1691#endif
1692#ifndef W_OK
1693#define W_OK 2
1694#endif
1695#ifndef X_OK
1696#define X_OK 1
1697#endif
1698
1699#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001700PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001701"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001702Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001703
1704static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001705posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001706{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001707 int id;
1708 char *ret;
1709
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001710 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001711 return NULL;
1712
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001713#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001714 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001715 if (id == 0) {
1716 ret = ttyname();
1717 }
1718 else {
1719 ret = NULL;
1720 }
1721#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001722 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001723#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001724 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001725 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001726 return PyUnicode_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001727}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001728#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001729
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001730#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001731PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001732"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001733Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001734
1735static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001736posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001737{
1738 char *ret;
1739 char buffer[L_ctermid];
1740
Greg Wardb48bc172000-03-01 21:51:56 +00001741#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001742 ret = ctermid_r(buffer);
1743#else
1744 ret = ctermid(buffer);
1745#endif
1746 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001747 return posix_error();
Neal Norwitz93c56822007-08-26 07:10:06 +00001748 return PyUnicode_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001749}
1750#endif
1751
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001752PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001753"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001754Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001755
Barry Warsaw53699e91996-12-10 23:23:01 +00001756static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001757posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001758{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001759#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00001760 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001761#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001762 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001763#elif defined(__VMS)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001764 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001765#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001766 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001767#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001768}
1769
Fred Drake4d1e64b2002-04-15 19:40:07 +00001770#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001771PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001772"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001773Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001774opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001775
1776static PyObject *
1777posix_fchdir(PyObject *self, PyObject *fdobj)
1778{
1779 return posix_fildes(fdobj, fchdir);
1780}
1781#endif /* HAVE_FCHDIR */
1782
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001783
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001784PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001785"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001786Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001787
Barry Warsaw53699e91996-12-10 23:23:01 +00001788static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001789posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001790{
Mark Hammondef8b6542001-05-13 08:04:26 +00001791 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001792 int i;
1793 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001794#ifdef Py_WIN_WIDE_FILENAMES
Thomas Wouters477c8d52006-05-27 19:21:47 +00001795 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001796 if (unicode_file_names()) {
1797 PyUnicodeObject *po;
1798 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1799 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001800 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1801 if (attr != 0xFFFFFFFF) {
1802 if (i & _S_IWRITE)
1803 attr &= ~FILE_ATTRIBUTE_READONLY;
1804 else
1805 attr |= FILE_ATTRIBUTE_READONLY;
1806 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1807 }
1808 else
1809 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001810 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001811 if (!res)
1812 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001813 PyUnicode_AS_UNICODE(po));
1814 Py_INCREF(Py_None);
1815 return Py_None;
1816 }
1817 /* Drop the argument parsing error as narrow strings
1818 are also valid. */
1819 PyErr_Clear();
1820 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001821 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1822 &path, &i))
1823 return NULL;
1824 Py_BEGIN_ALLOW_THREADS
1825 attr = GetFileAttributesA(path);
1826 if (attr != 0xFFFFFFFF) {
1827 if (i & _S_IWRITE)
1828 attr &= ~FILE_ATTRIBUTE_READONLY;
1829 else
1830 attr |= FILE_ATTRIBUTE_READONLY;
1831 res = SetFileAttributesA(path, attr);
1832 }
1833 else
1834 res = 0;
1835 Py_END_ALLOW_THREADS
1836 if (!res) {
1837 win32_error("chmod", path);
1838 PyMem_Free(path);
1839 return NULL;
1840 }
1841 PyMem_Free(path);
1842 Py_INCREF(Py_None);
1843 return Py_None;
1844#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001845 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001846 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001847 return NULL;
1848 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001849 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001850 Py_END_ALLOW_THREADS
1851 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001852 return posix_error_with_allocated_filename(path);
1853 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001854 Py_INCREF(Py_None);
1855 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001856#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001857}
1858
Christian Heimes4e30a842007-11-30 22:12:06 +00001859#ifdef HAVE_FCHMOD
1860PyDoc_STRVAR(posix_fchmod__doc__,
1861"fchmod(fd, mode)\n\n\
1862Change the access permissions of the file given by file\n\
1863descriptor fd.");
1864
1865static PyObject *
1866posix_fchmod(PyObject *self, PyObject *args)
1867{
1868 int fd, mode, res;
1869 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1870 return NULL;
1871 Py_BEGIN_ALLOW_THREADS
1872 res = fchmod(fd, mode);
1873 Py_END_ALLOW_THREADS
1874 if (res < 0)
1875 return posix_error();
1876 Py_RETURN_NONE;
1877}
1878#endif /* HAVE_FCHMOD */
1879
1880#ifdef HAVE_LCHMOD
1881PyDoc_STRVAR(posix_lchmod__doc__,
1882"lchmod(path, mode)\n\n\
1883Change the access permissions of a file. If path is a symlink, this\n\
1884affects the link itself rather than the target.");
1885
1886static PyObject *
1887posix_lchmod(PyObject *self, PyObject *args)
1888{
1889 char *path = NULL;
1890 int i;
1891 int res;
1892 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1893 &path, &i))
1894 return NULL;
1895 Py_BEGIN_ALLOW_THREADS
1896 res = lchmod(path, i);
1897 Py_END_ALLOW_THREADS
1898 if (res < 0)
1899 return posix_error_with_allocated_filename(path);
1900 PyMem_Free(path);
1901 Py_RETURN_NONE;
1902}
1903#endif /* HAVE_LCHMOD */
1904
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001905
Thomas Wouterscf297e42007-02-23 15:07:44 +00001906#ifdef HAVE_CHFLAGS
1907PyDoc_STRVAR(posix_chflags__doc__,
1908"chflags(path, flags)\n\n\
1909Set file flags.");
1910
1911static PyObject *
1912posix_chflags(PyObject *self, PyObject *args)
1913{
1914 char *path;
1915 unsigned long flags;
1916 int res;
1917 if (!PyArg_ParseTuple(args, "etk:chflags",
1918 Py_FileSystemDefaultEncoding, &path, &flags))
1919 return NULL;
1920 Py_BEGIN_ALLOW_THREADS
1921 res = chflags(path, flags);
1922 Py_END_ALLOW_THREADS
1923 if (res < 0)
1924 return posix_error_with_allocated_filename(path);
1925 PyMem_Free(path);
1926 Py_INCREF(Py_None);
1927 return Py_None;
1928}
1929#endif /* HAVE_CHFLAGS */
1930
1931#ifdef HAVE_LCHFLAGS
1932PyDoc_STRVAR(posix_lchflags__doc__,
1933"lchflags(path, flags)\n\n\
1934Set file flags.\n\
1935This function will not follow symbolic links.");
1936
1937static PyObject *
1938posix_lchflags(PyObject *self, PyObject *args)
1939{
1940 char *path;
1941 unsigned long flags;
1942 int res;
1943 if (!PyArg_ParseTuple(args, "etk:lchflags",
1944 Py_FileSystemDefaultEncoding, &path, &flags))
1945 return NULL;
1946 Py_BEGIN_ALLOW_THREADS
1947 res = lchflags(path, flags);
1948 Py_END_ALLOW_THREADS
1949 if (res < 0)
1950 return posix_error_with_allocated_filename(path);
1951 PyMem_Free(path);
1952 Py_INCREF(Py_None);
1953 return Py_None;
1954}
1955#endif /* HAVE_LCHFLAGS */
1956
Martin v. Löwis244edc82001-10-04 22:44:26 +00001957#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001958PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001959"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001960Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001961
1962static PyObject *
1963posix_chroot(PyObject *self, PyObject *args)
1964{
Thomas Wouters477c8d52006-05-27 19:21:47 +00001965 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001966}
1967#endif
1968
Guido van Rossum21142a01999-01-08 21:05:37 +00001969#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001970PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001971"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001972force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001973
1974static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001975posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001976{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001977 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001978}
1979#endif /* HAVE_FSYNC */
1980
1981#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001982
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001983#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001984extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1985#endif
1986
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001987PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001988"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001989force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001990 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001991
1992static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001993posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001994{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001995 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001996}
1997#endif /* HAVE_FDATASYNC */
1998
1999
Fredrik Lundh10723342000-07-10 16:38:09 +00002000#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002001PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002002"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002003Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002004
Barry Warsaw53699e91996-12-10 23:23:01 +00002005static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002006posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002007{
Mark Hammondef8b6542001-05-13 08:04:26 +00002008 char *path = NULL;
Christian Heimesd5e2b6f2008-03-19 21:50:51 +00002009 long uid, gid;
Fredrik Lundh44328e62000-07-10 15:59:30 +00002010 int res;
Christian Heimesd5e2b6f2008-03-19 21:50:51 +00002011 if (!PyArg_ParseTuple(args, "etll:chown",
Tim Peters5aa91602002-01-30 05:46:57 +00002012 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00002013 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00002014 return NULL;
2015 Py_BEGIN_ALLOW_THREADS
2016 res = chown(path, (uid_t) uid, (gid_t) gid);
2017 Py_END_ALLOW_THREADS
2018 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002019 return posix_error_with_allocated_filename(path);
2020 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00002021 Py_INCREF(Py_None);
2022 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002023}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002024#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002025
Christian Heimes4e30a842007-11-30 22:12:06 +00002026#ifdef HAVE_FCHOWN
2027PyDoc_STRVAR(posix_fchown__doc__,
2028"fchown(fd, uid, gid)\n\n\
2029Change the owner and group id of the file given by file descriptor\n\
2030fd to the numeric uid and gid.");
2031
2032static PyObject *
2033posix_fchown(PyObject *self, PyObject *args)
2034{
2035 int fd, uid, gid;
2036 int res;
2037 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
2038 return NULL;
2039 Py_BEGIN_ALLOW_THREADS
2040 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2041 Py_END_ALLOW_THREADS
2042 if (res < 0)
2043 return posix_error();
2044 Py_RETURN_NONE;
2045}
2046#endif /* HAVE_FCHOWN */
2047
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002048#ifdef HAVE_LCHOWN
2049PyDoc_STRVAR(posix_lchown__doc__,
2050"lchown(path, uid, gid)\n\n\
2051Change the owner and group id of path to the numeric uid and gid.\n\
2052This function will not follow symbolic links.");
2053
2054static PyObject *
2055posix_lchown(PyObject *self, PyObject *args)
2056{
2057 char *path = NULL;
2058 int uid, gid;
2059 int res;
2060 if (!PyArg_ParseTuple(args, "etii:lchown",
2061 Py_FileSystemDefaultEncoding, &path,
2062 &uid, &gid))
2063 return NULL;
2064 Py_BEGIN_ALLOW_THREADS
2065 res = lchown(path, (uid_t) uid, (gid_t) gid);
2066 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00002067 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002068 return posix_error_with_allocated_filename(path);
2069 PyMem_Free(path);
2070 Py_INCREF(Py_None);
2071 return Py_None;
2072}
2073#endif /* HAVE_LCHOWN */
2074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002075
Guido van Rossum36bc6801995-06-14 22:54:23 +00002076#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002077static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002078posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002079{
2080 char buf[1026];
2081 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002082
2083#ifdef Py_WIN_WIDE_FILENAMES
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002084 if (!use_bytes && unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002085 wchar_t wbuf[1026];
Thomas Wouters477c8d52006-05-27 19:21:47 +00002086 wchar_t *wbuf2 = wbuf;
2087 PyObject *resobj;
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002088 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002089 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002090 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2091 /* If the buffer is large enough, len does not include the
2092 terminating \0. If the buffer is too small, len includes
2093 the space needed for the terminator. */
2094 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2095 wbuf2 = malloc(len * sizeof(wchar_t));
2096 if (wbuf2)
2097 len = GetCurrentDirectoryW(len, wbuf2);
2098 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002099 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002100 if (!wbuf2) {
2101 PyErr_NoMemory();
2102 return NULL;
2103 }
2104 if (!len) {
2105 if (wbuf2 != wbuf) free(wbuf2);
2106 return win32_error("getcwdu", NULL);
2107 }
2108 resobj = PyUnicode_FromWideChar(wbuf2, len);
2109 if (wbuf2 != wbuf) free(wbuf2);
2110 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002111 }
2112#endif
2113
2114 Py_BEGIN_ALLOW_THREADS
2115#if defined(PYOS_OS2) && defined(PYCC_GCC)
2116 res = _getcwd2(buf, sizeof buf);
2117#else
2118 res = getcwd(buf, sizeof buf);
2119#endif
2120 Py_END_ALLOW_THREADS
2121 if (res == NULL)
2122 return posix_error();
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002123 if (use_bytes)
2124 return PyBytes_FromStringAndSize(buf, strlen(buf));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002125 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2126}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002127
2128PyDoc_STRVAR(posix_getcwd__doc__,
2129"getcwd() -> path\n\n\
2130Return a unicode string representing the current working directory.");
2131
2132static PyObject *
2133posix_getcwd_unicode(PyObject *self)
2134{
2135 return posix_getcwd(0);
2136}
2137
2138PyDoc_STRVAR(posix_getcwdb__doc__,
2139"getcwdb() -> path\n\n\
2140Return a bytes string representing the current working directory.");
2141
2142static PyObject *
2143posix_getcwd_bytes(PyObject *self)
2144{
2145 return posix_getcwd(1);
2146}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002147#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002148
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002149
Guido van Rossumb6775db1994-08-01 11:34:53 +00002150#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002151PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002152"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002153Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002154
Barry Warsaw53699e91996-12-10 23:23:01 +00002155static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002156posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002157{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002158 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002159}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002160#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002161
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002162
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002163PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002164"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002165Return a list containing the names of the entries in the directory.\n\
2166\n\
2167 path: path of directory to list\n\
2168\n\
2169The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002170entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002171
Barry Warsaw53699e91996-12-10 23:23:01 +00002172static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002173posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002174{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002175 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002176 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002177#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002178
Barry Warsaw53699e91996-12-10 23:23:01 +00002179 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002180 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002181 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002182 WIN32_FIND_DATA FileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002183 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00002184 char *bufptr = namebuf;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002185 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002186
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002187#ifdef Py_WIN_WIDE_FILENAMES
2188 /* If on wide-character-capable OS see if argument
2189 is Unicode and if so use wide API. */
2190 if (unicode_file_names()) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002191 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002192 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2193 WIN32_FIND_DATAW wFileData;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002194 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002195 Py_UNICODE wch;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002196 /* Overallocate for \\*.*\0 */
2197 len = PyUnicode_GET_SIZE(po);
2198 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2199 if (!wnamebuf) {
2200 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002201 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002202 }
2203 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2204 wch = len > 0 ? wnamebuf[len-1] : '\0';
2205 if (wch != L'/' && wch != L'\\' && wch != L':')
2206 wnamebuf[len++] = L'\\';
2207 wcscpy(wnamebuf + len, L"*.*");
2208 if ((d = PyList_New(0)) == NULL) {
2209 free(wnamebuf);
2210 return NULL;
2211 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002212 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2213 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002214 int error = GetLastError();
2215 if (error == ERROR_FILE_NOT_FOUND) {
2216 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002217 return d;
2218 }
2219 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002220 win32_error_unicode("FindFirstFileW", wnamebuf);
2221 free(wnamebuf);
2222 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002223 }
2224 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002225 /* Skip over . and .. */
2226 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2227 wcscmp(wFileData.cFileName, L"..") != 0) {
2228 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2229 if (v == NULL) {
2230 Py_DECREF(d);
2231 d = NULL;
2232 break;
2233 }
2234 if (PyList_Append(d, v) != 0) {
2235 Py_DECREF(v);
2236 Py_DECREF(d);
2237 d = NULL;
2238 break;
2239 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002240 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002241 }
Georg Brandl622927b2006-03-07 12:48:03 +00002242 Py_BEGIN_ALLOW_THREADS
2243 result = FindNextFileW(hFindFile, &wFileData);
2244 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002245 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2246 it got to the end of the directory. */
2247 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2248 Py_DECREF(d);
2249 win32_error_unicode("FindNextFileW", wnamebuf);
2250 FindClose(hFindFile);
2251 free(wnamebuf);
2252 return NULL;
2253 }
Georg Brandl622927b2006-03-07 12:48:03 +00002254 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002255
2256 if (FindClose(hFindFile) == FALSE) {
2257 Py_DECREF(d);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002258 win32_error_unicode("FindClose", wnamebuf);
2259 free(wnamebuf);
2260 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002261 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002262 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002263 return d;
2264 }
2265 /* Drop the argument parsing error as narrow strings
2266 are also valid. */
2267 PyErr_Clear();
2268 }
2269#endif
2270
Tim Peters5aa91602002-01-30 05:46:57 +00002271 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002272 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00002273 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00002274 if (len > 0) {
2275 char ch = namebuf[len-1];
2276 if (ch != SEP && ch != ALTSEP && ch != ':')
2277 namebuf[len++] = '/';
2278 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002279 strcpy(namebuf + len, "*.*");
2280
Barry Warsaw53699e91996-12-10 23:23:01 +00002281 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002282 return NULL;
2283
2284 hFindFile = FindFirstFile(namebuf, &FileData);
2285 if (hFindFile == INVALID_HANDLE_VALUE) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00002286 int error = GetLastError();
2287 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002288 return d;
2289 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002290 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002291 }
2292 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002293 /* Skip over . and .. */
2294 if (strcmp(FileData.cFileName, ".") != 0 &&
2295 strcmp(FileData.cFileName, "..") != 0) {
Christian Heimes72b710a2008-05-26 13:28:38 +00002296 v = PyBytes_FromString(FileData.cFileName);
Martin v. Löwise920f0d2006-03-07 23:59:33 +00002297 if (v == NULL) {
2298 Py_DECREF(d);
2299 d = NULL;
2300 break;
2301 }
2302 if (PyList_Append(d, v) != 0) {
2303 Py_DECREF(v);
2304 Py_DECREF(d);
2305 d = NULL;
2306 break;
2307 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002308 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002309 }
Georg Brandl622927b2006-03-07 12:48:03 +00002310 Py_BEGIN_ALLOW_THREADS
2311 result = FindNextFile(hFindFile, &FileData);
2312 Py_END_ALLOW_THREADS
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002313 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2314 it got to the end of the directory. */
2315 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2316 Py_DECREF(d);
2317 win32_error("FindNextFile", namebuf);
2318 FindClose(hFindFile);
2319 return NULL;
2320 }
Georg Brandl622927b2006-03-07 12:48:03 +00002321 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002322
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002323 if (FindClose(hFindFile) == FALSE) {
2324 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00002325 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002326 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002327
2328 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002329
Tim Peters0bb44a42000-09-15 07:44:49 +00002330#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002331
2332#ifndef MAX_PATH
2333#define MAX_PATH CCHMAXPATH
2334#endif
2335 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002336 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002337 PyObject *d, *v;
2338 char namebuf[MAX_PATH+5];
2339 HDIR hdir = 1;
2340 ULONG srchcnt = 1;
2341 FILEFINDBUF3 ep;
2342 APIRET rc;
2343
Alexandre Vassalotti70a23712007-10-14 02:05:51 +00002344 if (!PyArg_ParseTuple(args, "et#:listdir",
2345 Py_FileSystemDefaultEncoding, &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002346 return NULL;
2347 if (len >= MAX_PATH) {
Neal Norwitz6c913782007-10-14 03:23:09 +00002348 PyMem_Free(name);
2349 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002350 return NULL;
2351 }
2352 strcpy(namebuf, name);
2353 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002354 if (*pt == ALTSEP)
2355 *pt = SEP;
2356 if (namebuf[len-1] != SEP)
2357 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002358 strcpy(namebuf + len, "*.*");
2359
Neal Norwitz6c913782007-10-14 03:23:09 +00002360 if ((d = PyList_New(0)) == NULL) {
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002361 PyMem_Free(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002362 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002363 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002364
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002365 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2366 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002367 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002368 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2369 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2370 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002371
2372 if (rc != NO_ERROR) {
2373 errno = ENOENT;
Neal Norwitz6c913782007-10-14 03:23:09 +00002374 return posix_error_with_allocated_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002375 }
2376
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002377 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002378 do {
2379 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002380 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002381 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002382
2383 strcpy(namebuf, ep.achName);
2384
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002385 /* Leave Case of Name Alone -- In Native Form */
2386 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002387
Christian Heimes72b710a2008-05-26 13:28:38 +00002388 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002389 if (v == NULL) {
2390 Py_DECREF(d);
2391 d = NULL;
2392 break;
2393 }
2394 if (PyList_Append(d, v) != 0) {
2395 Py_DECREF(v);
2396 Py_DECREF(d);
2397 d = NULL;
2398 break;
2399 }
2400 Py_DECREF(v);
2401 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2402 }
2403
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002404 PyMem_Free(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002405 return d;
2406#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002407
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002408 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002409 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002410 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002411 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002412 int arg_is_unicode = 1;
2413
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002414 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002415 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2416 arg_is_unicode = 0;
2417 PyErr_Clear();
2418 }
2419 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002420 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002421 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002422 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002423 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002424 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002425 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002426 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002427 return NULL;
2428 }
Georg Brandl622927b2006-03-07 12:48:03 +00002429 for (;;) {
Georg Brandl3dbca812008-07-23 16:10:53 +00002430 errno = 0;
Georg Brandl622927b2006-03-07 12:48:03 +00002431 Py_BEGIN_ALLOW_THREADS
2432 ep = readdir(dirp);
2433 Py_END_ALLOW_THREADS
Georg Brandl3dbca812008-07-23 16:10:53 +00002434 if (ep == NULL) {
2435 if (errno == 0) {
2436 break;
2437 } else {
2438 closedir(dirp);
2439 Py_DECREF(d);
2440 return posix_error_with_allocated_filename(name);
2441 }
2442 }
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002443 if (ep->d_name[0] == '.' &&
2444 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002445 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002446 continue;
Christian Heimes72b710a2008-05-26 13:28:38 +00002447 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002448 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002449 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002450 d = NULL;
2451 break;
2452 }
Just van Rossum96b1c902003-03-03 17:32:15 +00002453 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002454 PyObject *w;
2455
2456 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002457 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002458 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002459 if (w != NULL) {
2460 Py_DECREF(v);
2461 v = w;
2462 }
2463 else {
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002464 /* Ignore undecodable filenames, as discussed
2465 * in issue 3187. To include these,
2466 * use getcwdb(). */
Just van Rossum6a421832003-03-04 19:30:44 +00002467 PyErr_Clear();
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002468 Py_DECREF(v);
2469 continue;
Just van Rossum46c97842003-02-25 21:42:15 +00002470 }
Just van Rossum46c97842003-02-25 21:42:15 +00002471 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002472 if (PyList_Append(d, v) != 0) {
2473 Py_DECREF(v);
2474 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002475 d = NULL;
2476 break;
2477 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002478 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002479 }
2480 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002481 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002482
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002483 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002484
Tim Peters0bb44a42000-09-15 07:44:49 +00002485#endif /* which OS */
2486} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002487
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002488#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002489/* A helper function for abspath on win32 */
2490static PyObject *
2491posix__getfullpathname(PyObject *self, PyObject *args)
2492{
Mark Dickinson934896d2009-02-21 20:59:32 +00002493 /* assume encoded strings won't more than double no of chars */
Mark Hammondef8b6542001-05-13 08:04:26 +00002494 char inbuf[MAX_PATH*2];
2495 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002496 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002497 char outbuf[MAX_PATH*2];
2498 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002499#ifdef Py_WIN_WIDE_FILENAMES
2500 if (unicode_file_names()) {
2501 PyUnicodeObject *po;
2502 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
Benjamin Petersonf608c612008-11-16 18:33:53 +00002503 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2504 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002505 Py_UNICODE *wtemp;
Benjamin Petersonf608c612008-11-16 18:33:53 +00002506 DWORD result;
2507 PyObject *v;
2508 result = GetFullPathNameW(wpath,
2509 sizeof(woutbuf)/sizeof(woutbuf[0]),
2510 woutbuf, &wtemp);
2511 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2512 woutbufp = malloc(result * sizeof(Py_UNICODE));
2513 if (!woutbufp)
2514 return PyErr_NoMemory();
2515 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2516 }
2517 if (result)
2518 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2519 else
2520 v = win32_error_unicode("GetFullPathNameW", wpath);
2521 if (woutbufp != woutbuf)
2522 free(woutbufp);
2523 return v;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002524 }
2525 /* Drop the argument parsing error as narrow strings
2526 are also valid. */
2527 PyErr_Clear();
2528 }
2529#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002530 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2531 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002532 &insize))
2533 return NULL;
2534 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2535 outbuf, &temp))
2536 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002537 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2538 return PyUnicode_Decode(outbuf, strlen(outbuf),
2539 Py_FileSystemDefaultEncoding, NULL);
2540 }
Christian Heimes72b710a2008-05-26 13:28:38 +00002541 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002542} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002543#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002544
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002545PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002546"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002547Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002548
Barry Warsaw53699e91996-12-10 23:23:01 +00002549static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002550posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002551{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002552 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002553 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002554 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002555
2556#ifdef Py_WIN_WIDE_FILENAMES
2557 if (unicode_file_names()) {
2558 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002559 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002560 Py_BEGIN_ALLOW_THREADS
2561 /* PyUnicode_AS_UNICODE OK without thread lock as
2562 it is a simple dereference. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002563 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002564 Py_END_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002565 if (!res)
2566 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002567 Py_INCREF(Py_None);
2568 return Py_None;
2569 }
2570 /* Drop the argument parsing error as narrow strings
2571 are also valid. */
2572 PyErr_Clear();
2573 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002574 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2575 Py_FileSystemDefaultEncoding, &path, &mode))
2576 return NULL;
2577 Py_BEGIN_ALLOW_THREADS
2578 /* PyUnicode_AS_UNICODE OK without thread lock as
2579 it is a simple dereference. */
2580 res = CreateDirectoryA(path, NULL);
2581 Py_END_ALLOW_THREADS
2582 if (!res) {
2583 win32_error("mkdir", path);
2584 PyMem_Free(path);
2585 return NULL;
2586 }
2587 PyMem_Free(path);
2588 Py_INCREF(Py_None);
2589 return Py_None;
2590#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002591
Tim Peters5aa91602002-01-30 05:46:57 +00002592 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002593 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002594 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002595 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002596#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002597 res = mkdir(path);
2598#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002599 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002600#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002601 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002602 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002603 return posix_error_with_allocated_filename(path);
2604 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002605 Py_INCREF(Py_None);
2606 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002607#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002608}
2609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002610
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002611/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2612#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002613#include <sys/resource.h>
2614#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002615
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002616
2617#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002618PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002619"nice(inc) -> new_priority\n\n\
2620Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002621
Barry Warsaw53699e91996-12-10 23:23:01 +00002622static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002623posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002624{
2625 int increment, value;
2626
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002627 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002628 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002629
2630 /* There are two flavours of 'nice': one that returns the new
2631 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002632 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2633 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002634
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002635 If we are of the nice family that returns the new priority, we
2636 need to clear errno before the call, and check if errno is filled
2637 before calling posix_error() on a returnvalue of -1, because the
2638 -1 may be the actual new priority! */
2639
2640 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002641 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002642#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002643 if (value == 0)
2644 value = getpriority(PRIO_PROCESS, 0);
2645#endif
2646 if (value == -1 && errno != 0)
2647 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002648 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00002649 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002650}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002651#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002652
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002653PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002654"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002655Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002656
Barry Warsaw53699e91996-12-10 23:23:01 +00002657static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002658posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002659{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002660#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002661 PyObject *o1, *o2;
2662 char *p1, *p2;
2663 BOOL result;
2664 if (unicode_file_names()) {
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002665 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2666 goto error;
2667 if (!convert_to_unicode(&o1))
2668 goto error;
2669 if (!convert_to_unicode(&o2)) {
2670 Py_DECREF(o1);
2671 goto error;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002672 }
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +00002673 Py_BEGIN_ALLOW_THREADS
2674 result = MoveFileW(PyUnicode_AsUnicode(o1),
2675 PyUnicode_AsUnicode(o2));
2676 Py_END_ALLOW_THREADS
2677 Py_DECREF(o1);
2678 Py_DECREF(o2);
2679 if (!result)
2680 return win32_error("rename", NULL);
2681 Py_INCREF(Py_None);
2682 return Py_None;
2683error:
2684 PyErr_Clear();
Thomas Wouters477c8d52006-05-27 19:21:47 +00002685 }
2686 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2687 return NULL;
2688 Py_BEGIN_ALLOW_THREADS
2689 result = MoveFileA(p1, p2);
2690 Py_END_ALLOW_THREADS
2691 if (!result)
2692 return win32_error("rename", NULL);
2693 Py_INCREF(Py_None);
2694 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002695#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002696 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002697#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002698}
2699
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002700
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002701PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002702"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002703Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002704
Barry Warsaw53699e91996-12-10 23:23:01 +00002705static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002706posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002707{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002708#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00002709 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002710#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002711 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002712#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002713}
2714
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002715
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002716PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002717"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002718Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002719
Barry Warsaw53699e91996-12-10 23:23:01 +00002720static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002721posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002722{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002723#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002724 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002725#else
2726 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2727#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002728}
2729
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002730
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002731#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002732PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002733"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002734Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002735
Barry Warsaw53699e91996-12-10 23:23:01 +00002736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002737posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002738{
Guido van Rossumff4949e1992-08-05 19:58:53 +00002739 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002740#ifdef MS_WINDOWS
2741 wchar_t *command;
2742 if (!PyArg_ParseTuple(args, "u:system", &command))
2743 return NULL;
2744#else
2745 char *command;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002746 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002747 return NULL;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002748#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002749 Py_BEGIN_ALLOW_THREADS
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002750#ifdef MS_WINDOWS
2751 sts = _wsystem(command);
2752#else
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002753 sts = system(command);
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002754#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002755 Py_END_ALLOW_THREADS
Christian Heimes217cfd12007-12-02 14:31:20 +00002756 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002757}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002758#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002759
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002760
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002761PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002762"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002763Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002764
Barry Warsaw53699e91996-12-10 23:23:01 +00002765static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002766posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002767{
2768 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002769 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002770 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002771 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002772 if (i < 0)
2773 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00002774 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002775}
2776
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002777
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002778PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002779"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002780Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002781
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002782PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002783"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002784Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002785
Barry Warsaw53699e91996-12-10 23:23:01 +00002786static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002787posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002788{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002789#ifdef MS_WINDOWS
Amaury Forgeot d'Arcc72ef8b2008-10-03 18:38:26 +00002790 return win32_1str(args, "remove", "y:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002791#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002792 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002793#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002794}
2795
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002796
Guido van Rossumb6775db1994-08-01 11:34:53 +00002797#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002798PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002799"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002800Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002801
Barry Warsaw53699e91996-12-10 23:23:01 +00002802static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002803posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002804{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002805 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002806 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002807
Barry Warsaw53699e91996-12-10 23:23:01 +00002808 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002809 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002810 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002811 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002812 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002813 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002814 u.sysname,
2815 u.nodename,
2816 u.release,
2817 u.version,
2818 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002819}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002820#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002821
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002822static int
2823extract_time(PyObject *t, long* sec, long* usec)
2824{
2825 long intval;
2826 if (PyFloat_Check(t)) {
2827 double tval = PyFloat_AsDouble(t);
Christian Heimes90aa7642007-12-19 02:45:37 +00002828 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002829 if (!intobj)
2830 return -1;
Christian Heimes217cfd12007-12-02 14:31:20 +00002831 intval = PyLong_AsLong(intobj);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002832 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002833 if (intval == -1 && PyErr_Occurred())
2834 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002835 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002836 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002837 if (*usec < 0)
2838 /* If rounding gave us a negative number,
2839 truncate. */
2840 *usec = 0;
2841 return 0;
2842 }
Christian Heimes217cfd12007-12-02 14:31:20 +00002843 intval = PyLong_AsLong(t);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002844 if (intval == -1 && PyErr_Occurred())
2845 return -1;
2846 *sec = intval;
2847 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002848 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002849}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002850
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002851PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00002852"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002853utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002854Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002855second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002856
Barry Warsaw53699e91996-12-10 23:23:01 +00002857static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002858posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002859{
Thomas Wouters477c8d52006-05-27 19:21:47 +00002860#ifdef Py_WIN_WIDE_FILENAMES
2861 PyObject *arg;
2862 PyUnicodeObject *obwpath;
2863 wchar_t *wpath = NULL;
2864 char *apath = NULL;
2865 HANDLE hFile;
2866 long atimesec, mtimesec, ausec, musec;
2867 FILETIME atime, mtime;
2868 PyObject *result = NULL;
2869
2870 if (unicode_file_names()) {
2871 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2872 wpath = PyUnicode_AS_UNICODE(obwpath);
2873 Py_BEGIN_ALLOW_THREADS
2874 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002875 NULL, OPEN_EXISTING,
2876 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002877 Py_END_ALLOW_THREADS
2878 if (hFile == INVALID_HANDLE_VALUE)
2879 return win32_error_unicode("utime", wpath);
2880 } else
2881 /* Drop the argument parsing error as narrow strings
2882 are also valid. */
2883 PyErr_Clear();
2884 }
2885 if (!wpath) {
2886 if (!PyArg_ParseTuple(args, "etO:utime",
2887 Py_FileSystemDefaultEncoding, &apath, &arg))
2888 return NULL;
2889 Py_BEGIN_ALLOW_THREADS
2890 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Thomas Wouters89f507f2006-12-13 04:49:30 +00002891 NULL, OPEN_EXISTING,
2892 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002893 Py_END_ALLOW_THREADS
2894 if (hFile == INVALID_HANDLE_VALUE) {
2895 win32_error("utime", apath);
2896 PyMem_Free(apath);
2897 return NULL;
2898 }
2899 PyMem_Free(apath);
2900 }
2901
2902 if (arg == Py_None) {
2903 SYSTEMTIME now;
2904 GetSystemTime(&now);
2905 if (!SystemTimeToFileTime(&now, &mtime) ||
2906 !SystemTimeToFileTime(&now, &atime)) {
2907 win32_error("utime", NULL);
2908 goto done;
2909 }
2910 }
2911 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2912 PyErr_SetString(PyExc_TypeError,
2913 "utime() arg 2 must be a tuple (atime, mtime)");
2914 goto done;
2915 }
2916 else {
2917 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2918 &atimesec, &ausec) == -1)
2919 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002920 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002921 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2922 &mtimesec, &musec) == -1)
2923 goto done;
Thomas Wouters89f507f2006-12-13 04:49:30 +00002924 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002925 }
2926 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2927 /* Avoid putting the file name into the error here,
2928 as that may confuse the user into believing that
2929 something is wrong with the file, when it also
2930 could be the time stamp that gives a problem. */
2931 win32_error("utime", NULL);
2932 }
2933 Py_INCREF(Py_None);
2934 result = Py_None;
2935done:
2936 CloseHandle(hFile);
2937 return result;
2938#else /* Py_WIN_WIDE_FILENAMES */
2939
Neal Norwitz2adf2102004-06-09 01:46:02 +00002940 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002941 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002942 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002943 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002944
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002945#if defined(HAVE_UTIMES)
2946 struct timeval buf[2];
2947#define ATIME buf[0].tv_sec
2948#define MTIME buf[1].tv_sec
2949#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002950/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002951 struct utimbuf buf;
2952#define ATIME buf.actime
2953#define MTIME buf.modtime
2954#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002955#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002956 time_t buf[2];
2957#define ATIME buf[0]
2958#define MTIME buf[1]
2959#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002960#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002961
Mark Hammond817c9292003-12-03 01:22:38 +00002962
Thomas Wouters477c8d52006-05-27 19:21:47 +00002963 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002964 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002965 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002966 if (arg == Py_None) {
2967 /* optional time values not given */
2968 Py_BEGIN_ALLOW_THREADS
2969 res = utime(path, NULL);
2970 Py_END_ALLOW_THREADS
2971 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002972 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002973 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002974 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002975 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002976 return NULL;
2977 }
2978 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002979 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002980 &atime, &ausec) == -1) {
2981 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002982 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002983 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002984 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002985 &mtime, &musec) == -1) {
2986 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002987 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002988 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002989 ATIME = atime;
2990 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002991#ifdef HAVE_UTIMES
2992 buf[0].tv_usec = ausec;
2993 buf[1].tv_usec = musec;
2994 Py_BEGIN_ALLOW_THREADS
2995 res = utimes(path, buf);
2996 Py_END_ALLOW_THREADS
2997#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002998 Py_BEGIN_ALLOW_THREADS
2999 res = utime(path, UTIME_ARG);
3000 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003001#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00003002 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00003003 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00003004 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00003005 }
Neal Norwitz96652712004-06-06 20:40:27 +00003006 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003007 Py_INCREF(Py_None);
3008 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003009#undef UTIME_ARG
3010#undef ATIME
3011#undef MTIME
Thomas Wouters477c8d52006-05-27 19:21:47 +00003012#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003013}
3014
Guido van Rossum85e3b011991-06-03 12:42:10 +00003015
Guido van Rossum3b066191991-06-04 19:40:25 +00003016/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003017
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003018PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003019"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003020Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003021
Barry Warsaw53699e91996-12-10 23:23:01 +00003022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003023posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003024{
3025 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003026 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003027 return NULL;
3028 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00003029 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003030}
3031
Martin v. Löwis114619e2002-10-07 06:44:21 +00003032#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3033static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003034free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003035{
Martin v. Löwis725507b2006-03-07 12:08:51 +00003036 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00003037 for (i = 0; i < count; i++)
3038 PyMem_Free(array[i]);
3039 PyMem_DEL(array);
3040}
3041#endif
3042
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003043
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003044#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003045PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003046"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003047Execute an executable path with arguments, replacing current process.\n\
3048\n\
3049 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003050 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003051
Barry Warsaw53699e91996-12-10 23:23:01 +00003052static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003053posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003054{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003055 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003056 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003057 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003058 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003059 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003060
Guido van Rossum89b33251993-10-22 14:26:06 +00003061 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00003062 argv is a list or tuple of strings. */
3063
Martin v. Löwis114619e2002-10-07 06:44:21 +00003064 if (!PyArg_ParseTuple(args, "etO:execv",
3065 Py_FileSystemDefaultEncoding,
3066 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003067 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003068 if (PyList_Check(argv)) {
3069 argc = PyList_Size(argv);
3070 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003071 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003072 else if (PyTuple_Check(argv)) {
3073 argc = PyTuple_Size(argv);
3074 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003075 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003076 else {
Fred Drake661ea262000-10-24 19:57:45 +00003077 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003078 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00003079 return NULL;
3080 }
Thomas Heller6790d602007-08-30 17:15:14 +00003081 if (argc < 1) {
3082 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3083 PyMem_Free(path);
3084 return NULL;
3085 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003086
Barry Warsaw53699e91996-12-10 23:23:01 +00003087 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003088 if (argvlist == NULL) {
3089 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003090 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003091 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003092 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003093 if (!PyArg_Parse((*getitem)(argv, i), "et",
3094 Py_FileSystemDefaultEncoding,
3095 &argvlist[i])) {
3096 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00003097 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00003098 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003099 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00003100 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003101
Guido van Rossum85e3b011991-06-03 12:42:10 +00003102 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00003103 }
3104 argvlist[argc] = NULL;
3105
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003106 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003107
Guido van Rossum85e3b011991-06-03 12:42:10 +00003108 /* If we get here it's definitely an error */
3109
Martin v. Löwis114619e2002-10-07 06:44:21 +00003110 free_string_array(argvlist, argc);
3111 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003112 return posix_error();
3113}
3114
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003115
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003116PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003117"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003118Execute a path with arguments and environment, replacing current process.\n\
3119\n\
3120 path: path of executable file\n\
3121 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003122 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003123
Barry Warsaw53699e91996-12-10 23:23:01 +00003124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003125posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003126{
3127 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00003128 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003129 char **argvlist;
3130 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003131 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00003132 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003133 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003134 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003135
3136 /* execve has three arguments: (path, argv, env), where
3137 argv is a list or tuple of strings and env is a dictionary
3138 like posix.environ. */
3139
Martin v. Löwis114619e2002-10-07 06:44:21 +00003140 if (!PyArg_ParseTuple(args, "etOO:execve",
3141 Py_FileSystemDefaultEncoding,
3142 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003143 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003144 if (PyList_Check(argv)) {
3145 argc = PyList_Size(argv);
3146 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003147 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003148 else if (PyTuple_Check(argv)) {
3149 argc = PyTuple_Size(argv);
3150 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003151 }
3152 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003153 PyErr_SetString(PyExc_TypeError,
3154 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003155 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003156 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003157 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003158 PyErr_SetString(PyExc_TypeError,
3159 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003160 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003161 }
3162
Barry Warsaw53699e91996-12-10 23:23:01 +00003163 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003164 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003165 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003166 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003167 }
3168 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003169 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00003170 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00003171 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00003172 &argvlist[i]))
3173 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003174 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003175 goto fail_1;
3176 }
3177 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003178 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003179 argvlist[argc] = NULL;
3180
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003181 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003182 if (i < 0)
3183 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00003184 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003185 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003186 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003187 goto fail_1;
3188 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003189 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003190 keys = PyMapping_Keys(env);
3191 vals = PyMapping_Values(env);
3192 if (!keys || !vals)
3193 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003194 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3195 PyErr_SetString(PyExc_TypeError,
3196 "execve(): env.keys() or env.values() is not a list");
3197 goto fail_2;
3198 }
Tim Peters5aa91602002-01-30 05:46:57 +00003199
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003200 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003201 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003202 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003203
3204 key = PyList_GetItem(keys, pos);
3205 val = PyList_GetItem(vals, pos);
3206 if (!key || !val)
3207 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003208
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003209 if (!PyArg_Parse(
3210 key,
3211 "s;execve() arg 3 contains a non-string key",
3212 &k) ||
3213 !PyArg_Parse(
3214 val,
3215 "s;execve() arg 3 contains a non-string value",
3216 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003217 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003218 goto fail_2;
3219 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003220
3221#if defined(PYOS_OS2)
3222 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3223 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3224#endif
Christian Heimes830a4bc2007-11-22 07:43:40 +00003225 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003226 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003227 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003228 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003229 goto fail_2;
3230 }
Tim Petersc8996f52001-12-03 20:41:00 +00003231 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003232 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003233#if defined(PYOS_OS2)
3234 }
3235#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003236 }
3237 envlist[envc] = 0;
3238
3239 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003240
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003241 /* If we get here it's definitely an error */
3242
3243 (void) posix_error();
3244
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003245 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003246 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00003247 PyMem_DEL(envlist[envc]);
3248 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003249 fail_1:
3250 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003251 Py_XDECREF(vals);
3252 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003253 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003254 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003255 return NULL;
3256}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003257#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003258
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003259
Guido van Rossuma1065681999-01-25 23:20:23 +00003260#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003261PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003262"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003263Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003264\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003265 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003266 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003267 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003268
3269static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003270posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003271{
3272 char *path;
3273 PyObject *argv;
3274 char **argvlist;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003275 int mode, i;
3276 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00003277 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003278 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003279
3280 /* spawnv has three arguments: (mode, path, argv), where
3281 argv is a list or tuple of strings. */
3282
Martin v. Löwis114619e2002-10-07 06:44:21 +00003283 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3284 Py_FileSystemDefaultEncoding,
3285 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00003286 return NULL;
3287 if (PyList_Check(argv)) {
3288 argc = PyList_Size(argv);
3289 getitem = PyList_GetItem;
3290 }
3291 else if (PyTuple_Check(argv)) {
3292 argc = PyTuple_Size(argv);
3293 getitem = PyTuple_GetItem;
3294 }
3295 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003296 PyErr_SetString(PyExc_TypeError,
3297 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003298 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003299 return NULL;
3300 }
3301
3302 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003303 if (argvlist == NULL) {
3304 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00003305 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003306 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003307 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003308 if (!PyArg_Parse((*getitem)(argv, i), "et",
3309 Py_FileSystemDefaultEncoding,
3310 &argvlist[i])) {
3311 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003312 PyErr_SetString(
3313 PyExc_TypeError,
3314 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003315 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00003316 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003317 }
3318 }
3319 argvlist[argc] = NULL;
3320
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003321#if defined(PYOS_OS2) && defined(PYCC_GCC)
3322 Py_BEGIN_ALLOW_THREADS
3323 spawnval = spawnv(mode, path, argvlist);
3324 Py_END_ALLOW_THREADS
3325#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003326 if (mode == _OLD_P_OVERLAY)
3327 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003328
Tim Peters25059d32001-12-07 20:35:43 +00003329 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003330 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00003331 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003332#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003333
Martin v. Löwis114619e2002-10-07 06:44:21 +00003334 free_string_array(argvlist, argc);
3335 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003336
Fred Drake699f3522000-06-29 21:12:41 +00003337 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003338 return posix_error();
3339 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003340#if SIZEOF_LONG == SIZEOF_VOID_P
3341 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003342#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003343 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003344#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003345}
3346
3347
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003348PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003349"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003350Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003351\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00003352 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003353 path: path of executable file\n\
3354 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003355 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003356
3357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003358posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003359{
3360 char *path;
3361 PyObject *argv, *env;
3362 char **argvlist;
3363 char **envlist;
3364 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003365 int mode, pos, envc;
3366 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00003367 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003368 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003369 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003370
3371 /* spawnve has four arguments: (mode, path, argv, env), where
3372 argv is a list or tuple of strings and env is a dictionary
3373 like posix.environ. */
3374
Martin v. Löwis114619e2002-10-07 06:44:21 +00003375 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3376 Py_FileSystemDefaultEncoding,
3377 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00003378 return NULL;
3379 if (PyList_Check(argv)) {
3380 argc = PyList_Size(argv);
3381 getitem = PyList_GetItem;
3382 }
3383 else if (PyTuple_Check(argv)) {
3384 argc = PyTuple_Size(argv);
3385 getitem = PyTuple_GetItem;
3386 }
3387 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003388 PyErr_SetString(PyExc_TypeError,
3389 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003390 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003391 }
3392 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003393 PyErr_SetString(PyExc_TypeError,
3394 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00003395 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003396 }
3397
3398 argvlist = PyMem_NEW(char *, argc+1);
3399 if (argvlist == NULL) {
3400 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00003401 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003402 }
3403 for (i = 0; i < argc; i++) {
3404 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003405 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00003406 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00003407 &argvlist[i]))
3408 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00003409 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00003410 goto fail_1;
3411 }
3412 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00003413 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00003414 argvlist[argc] = NULL;
3415
Jeremy Hylton03657cf2000-07-12 13:05:33 +00003416 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003417 if (i < 0)
3418 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003419 envlist = PyMem_NEW(char *, i + 1);
3420 if (envlist == NULL) {
3421 PyErr_NoMemory();
3422 goto fail_1;
3423 }
3424 envc = 0;
3425 keys = PyMapping_Keys(env);
3426 vals = PyMapping_Values(env);
3427 if (!keys || !vals)
3428 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003429 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3430 PyErr_SetString(PyExc_TypeError,
3431 "spawnve(): env.keys() or env.values() is not a list");
3432 goto fail_2;
3433 }
Tim Peters5aa91602002-01-30 05:46:57 +00003434
Guido van Rossuma1065681999-01-25 23:20:23 +00003435 for (pos = 0; pos < i; pos++) {
3436 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003437 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003438
3439 key = PyList_GetItem(keys, pos);
3440 val = PyList_GetItem(vals, pos);
3441 if (!key || !val)
3442 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003443
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003444 if (!PyArg_Parse(
3445 key,
3446 "s;spawnve() arg 3 contains a non-string key",
3447 &k) ||
3448 !PyArg_Parse(
3449 val,
3450 "s;spawnve() arg 3 contains a non-string value",
3451 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003452 {
3453 goto fail_2;
3454 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003455 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Tim Petersc8996f52001-12-03 20:41:00 +00003456 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003457 if (p == NULL) {
3458 PyErr_NoMemory();
3459 goto fail_2;
3460 }
Tim Petersc8996f52001-12-03 20:41:00 +00003461 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003462 envlist[envc++] = p;
3463 }
3464 envlist[envc] = 0;
3465
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003466#if defined(PYOS_OS2) && defined(PYCC_GCC)
3467 Py_BEGIN_ALLOW_THREADS
3468 spawnval = spawnve(mode, path, argvlist, envlist);
3469 Py_END_ALLOW_THREADS
3470#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003471 if (mode == _OLD_P_OVERLAY)
3472 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003473
3474 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003475 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003476 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003477#endif
Tim Peters25059d32001-12-07 20:35:43 +00003478
Fred Drake699f3522000-06-29 21:12:41 +00003479 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003480 (void) posix_error();
3481 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003482#if SIZEOF_LONG == SIZEOF_VOID_P
3483 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003484#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003485 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003486#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003487
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003488 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003489 while (--envc >= 0)
3490 PyMem_DEL(envlist[envc]);
3491 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003492 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003493 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003494 Py_XDECREF(vals);
3495 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003496 fail_0:
3497 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003498 return res;
3499}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003500
3501/* OS/2 supports spawnvp & spawnvpe natively */
3502#if defined(PYOS_OS2)
3503PyDoc_STRVAR(posix_spawnvp__doc__,
3504"spawnvp(mode, file, args)\n\n\
3505Execute the program 'file' in a new process, using the environment\n\
3506search path to find the file.\n\
3507\n\
3508 mode: mode of process creation\n\
3509 file: executable file name\n\
3510 args: tuple or list of strings");
3511
3512static PyObject *
3513posix_spawnvp(PyObject *self, PyObject *args)
3514{
3515 char *path;
3516 PyObject *argv;
3517 char **argvlist;
3518 int mode, i, argc;
3519 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003520 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003521
3522 /* spawnvp has three arguments: (mode, path, argv), where
3523 argv is a list or tuple of strings. */
3524
3525 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3526 Py_FileSystemDefaultEncoding,
3527 &path, &argv))
3528 return NULL;
3529 if (PyList_Check(argv)) {
3530 argc = PyList_Size(argv);
3531 getitem = PyList_GetItem;
3532 }
3533 else if (PyTuple_Check(argv)) {
3534 argc = PyTuple_Size(argv);
3535 getitem = PyTuple_GetItem;
3536 }
3537 else {
3538 PyErr_SetString(PyExc_TypeError,
3539 "spawnvp() arg 2 must be a tuple or list");
3540 PyMem_Free(path);
3541 return NULL;
3542 }
3543
3544 argvlist = PyMem_NEW(char *, argc+1);
3545 if (argvlist == NULL) {
3546 PyMem_Free(path);
3547 return PyErr_NoMemory();
3548 }
3549 for (i = 0; i < argc; i++) {
3550 if (!PyArg_Parse((*getitem)(argv, i), "et",
3551 Py_FileSystemDefaultEncoding,
3552 &argvlist[i])) {
3553 free_string_array(argvlist, i);
3554 PyErr_SetString(
3555 PyExc_TypeError,
3556 "spawnvp() arg 2 must contain only strings");
3557 PyMem_Free(path);
3558 return NULL;
3559 }
3560 }
3561 argvlist[argc] = NULL;
3562
3563 Py_BEGIN_ALLOW_THREADS
3564#if defined(PYCC_GCC)
3565 spawnval = spawnvp(mode, path, argvlist);
3566#else
3567 spawnval = _spawnvp(mode, path, argvlist);
3568#endif
3569 Py_END_ALLOW_THREADS
3570
3571 free_string_array(argvlist, argc);
3572 PyMem_Free(path);
3573
3574 if (spawnval == -1)
3575 return posix_error();
3576 else
3577 return Py_BuildValue("l", (long) spawnval);
3578}
3579
3580
3581PyDoc_STRVAR(posix_spawnvpe__doc__,
3582"spawnvpe(mode, file, args, env)\n\n\
3583Execute the program 'file' in a new process, using the environment\n\
3584search path to find the file.\n\
3585\n\
3586 mode: mode of process creation\n\
3587 file: executable file name\n\
3588 args: tuple or list of arguments\n\
3589 env: dictionary of strings mapping to strings");
3590
3591static PyObject *
3592posix_spawnvpe(PyObject *self, PyObject *args)
3593{
3594 char *path;
3595 PyObject *argv, *env;
3596 char **argvlist;
3597 char **envlist;
3598 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3599 int mode, i, pos, argc, envc;
3600 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003601 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003602 int lastarg = 0;
3603
3604 /* spawnvpe has four arguments: (mode, path, argv, env), where
3605 argv is a list or tuple of strings and env is a dictionary
3606 like posix.environ. */
3607
3608 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3609 Py_FileSystemDefaultEncoding,
3610 &path, &argv, &env))
3611 return NULL;
3612 if (PyList_Check(argv)) {
3613 argc = PyList_Size(argv);
3614 getitem = PyList_GetItem;
3615 }
3616 else if (PyTuple_Check(argv)) {
3617 argc = PyTuple_Size(argv);
3618 getitem = PyTuple_GetItem;
3619 }
3620 else {
3621 PyErr_SetString(PyExc_TypeError,
3622 "spawnvpe() arg 2 must be a tuple or list");
3623 goto fail_0;
3624 }
3625 if (!PyMapping_Check(env)) {
3626 PyErr_SetString(PyExc_TypeError,
3627 "spawnvpe() arg 3 must be a mapping object");
3628 goto fail_0;
3629 }
3630
3631 argvlist = PyMem_NEW(char *, argc+1);
3632 if (argvlist == NULL) {
3633 PyErr_NoMemory();
3634 goto fail_0;
3635 }
3636 for (i = 0; i < argc; i++) {
3637 if (!PyArg_Parse((*getitem)(argv, i),
3638 "et;spawnvpe() arg 2 must contain only strings",
3639 Py_FileSystemDefaultEncoding,
3640 &argvlist[i]))
3641 {
3642 lastarg = i;
3643 goto fail_1;
3644 }
3645 }
3646 lastarg = argc;
3647 argvlist[argc] = NULL;
3648
3649 i = PyMapping_Size(env);
3650 if (i < 0)
3651 goto fail_1;
3652 envlist = PyMem_NEW(char *, i + 1);
3653 if (envlist == NULL) {
3654 PyErr_NoMemory();
3655 goto fail_1;
3656 }
3657 envc = 0;
3658 keys = PyMapping_Keys(env);
3659 vals = PyMapping_Values(env);
3660 if (!keys || !vals)
3661 goto fail_2;
3662 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3663 PyErr_SetString(PyExc_TypeError,
3664 "spawnvpe(): env.keys() or env.values() is not a list");
3665 goto fail_2;
3666 }
3667
3668 for (pos = 0; pos < i; pos++) {
3669 char *p, *k, *v;
3670 size_t len;
3671
3672 key = PyList_GetItem(keys, pos);
3673 val = PyList_GetItem(vals, pos);
3674 if (!key || !val)
3675 goto fail_2;
3676
3677 if (!PyArg_Parse(
3678 key,
3679 "s;spawnvpe() arg 3 contains a non-string key",
3680 &k) ||
3681 !PyArg_Parse(
3682 val,
3683 "s;spawnvpe() arg 3 contains a non-string value",
3684 &v))
3685 {
3686 goto fail_2;
3687 }
Christian Heimes830a4bc2007-11-22 07:43:40 +00003688 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003689 p = PyMem_NEW(char, len);
3690 if (p == NULL) {
3691 PyErr_NoMemory();
3692 goto fail_2;
3693 }
3694 PyOS_snprintf(p, len, "%s=%s", k, v);
3695 envlist[envc++] = p;
3696 }
3697 envlist[envc] = 0;
3698
3699 Py_BEGIN_ALLOW_THREADS
3700#if defined(PYCC_GCC)
Christian Heimes292d3512008-02-03 16:51:08 +00003701 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003702#else
Christian Heimes292d3512008-02-03 16:51:08 +00003703 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003704#endif
3705 Py_END_ALLOW_THREADS
3706
3707 if (spawnval == -1)
3708 (void) posix_error();
3709 else
3710 res = Py_BuildValue("l", (long) spawnval);
3711
3712 fail_2:
3713 while (--envc >= 0)
3714 PyMem_DEL(envlist[envc]);
3715 PyMem_DEL(envlist);
3716 fail_1:
3717 free_string_array(argvlist, lastarg);
3718 Py_XDECREF(vals);
3719 Py_XDECREF(keys);
3720 fail_0:
3721 PyMem_Free(path);
3722 return res;
3723}
3724#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003725#endif /* HAVE_SPAWNV */
3726
3727
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003728#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003729PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003730"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003731Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3732\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003733Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003734
3735static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003736posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003737{
Christian Heimes400adb02008-02-01 08:12:03 +00003738 pid_t pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003739 if (pid == -1)
3740 return posix_error();
Georg Brandl2ee470f2008-07-16 12:55:28 +00003741 if (pid == 0)
3742 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003743 return PyLong_FromLong(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003744}
3745#endif
3746
3747
Guido van Rossumad0ee831995-03-01 10:34:45 +00003748#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003749PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003750"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003751Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003752Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003753
Barry Warsaw53699e91996-12-10 23:23:01 +00003754static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003755posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003756{
Christian Heimes400adb02008-02-01 08:12:03 +00003757 pid_t pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003758 if (pid == -1)
3759 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003760 if (pid == 0)
3761 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003762 return PyLong_FromLong(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003763}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003764#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003765
Neal Norwitzb59798b2003-03-21 01:43:31 +00003766/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003767/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3768#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003769#define DEV_PTY_FILE "/dev/ptc"
3770#define HAVE_DEV_PTMX
3771#else
3772#define DEV_PTY_FILE "/dev/ptmx"
3773#endif
3774
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003775#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003776#ifdef HAVE_PTY_H
3777#include <pty.h>
3778#else
3779#ifdef HAVE_LIBUTIL_H
3780#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003781#endif /* HAVE_LIBUTIL_H */
3782#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003783#ifdef HAVE_STROPTS_H
3784#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003785#endif
3786#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003787
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003788#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003789PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003790"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003791Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003792
3793static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003794posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003795{
3796 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003797#ifndef HAVE_OPENPTY
3798 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003799#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003800#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003801 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003802#ifdef sun
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003803 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003804#endif
3805#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003806
Thomas Wouters70c21a12000-07-14 14:28:33 +00003807#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003808 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3809 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003810#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003811 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3812 if (slave_name == NULL)
3813 return posix_error();
3814
3815 slave_fd = open(slave_name, O_RDWR);
3816 if (slave_fd < 0)
3817 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003818#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003819 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003820 if (master_fd < 0)
3821 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003822 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003823 /* change permission of slave */
3824 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003825 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003826 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003827 }
3828 /* unlock slave */
3829 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003830 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003831 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003832 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003833 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003834 slave_name = ptsname(master_fd); /* get name of slave */
3835 if (slave_name == NULL)
3836 return posix_error();
3837 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3838 if (slave_fd < 0)
3839 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003840#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003841 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3842 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003843#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003844 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003845#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003846#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003847#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003848
Fred Drake8cef4cf2000-06-28 16:40:38 +00003849 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003850
Fred Drake8cef4cf2000-06-28 16:40:38 +00003851}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003852#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003853
3854#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003855PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003856"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003857Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3858Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003859To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003860
3861static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003862posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003863{
Christian Heimes400adb02008-02-01 08:12:03 +00003864 int master_fd = -1;
3865 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003866
Fred Drake8cef4cf2000-06-28 16:40:38 +00003867 pid = forkpty(&master_fd, NULL, NULL, NULL);
3868 if (pid == -1)
3869 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003870 if (pid == 0)
3871 PyOS_AfterFork();
Christian Heimes400adb02008-02-01 08:12:03 +00003872 return Py_BuildValue("(li)", pid, master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003873}
3874#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003875
Guido van Rossumad0ee831995-03-01 10:34:45 +00003876#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003877PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003878"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003879Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003880
Barry Warsaw53699e91996-12-10 23:23:01 +00003881static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003882posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003883{
Christian Heimes217cfd12007-12-02 14:31:20 +00003884 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003885}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003886#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003887
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003888
Guido van Rossumad0ee831995-03-01 10:34:45 +00003889#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003890PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003891"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003892Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003893
Barry Warsaw53699e91996-12-10 23:23:01 +00003894static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003895posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003896{
Christian Heimes217cfd12007-12-02 14:31:20 +00003897 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003898}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003899#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003901
Guido van Rossumad0ee831995-03-01 10:34:45 +00003902#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003903PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003904"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003905Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003906
Barry Warsaw53699e91996-12-10 23:23:01 +00003907static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003908posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003909{
Christian Heimes217cfd12007-12-02 14:31:20 +00003910 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003911}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003912#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003913
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003914
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003915PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003916"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003917Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003918
Barry Warsaw53699e91996-12-10 23:23:01 +00003919static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003920posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003921{
Christian Heimes217cfd12007-12-02 14:31:20 +00003922 return PyLong_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003923}
3924
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003925
Fred Drakec9680921999-12-13 16:37:25 +00003926#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003927PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003928"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003929Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003930
3931static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003932posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003933{
3934 PyObject *result = NULL;
3935
Fred Drakec9680921999-12-13 16:37:25 +00003936#ifdef NGROUPS_MAX
3937#define MAX_GROUPS NGROUPS_MAX
3938#else
3939 /* defined to be 16 on Solaris7, so this should be a small number */
3940#define MAX_GROUPS 64
3941#endif
3942 gid_t grouplist[MAX_GROUPS];
3943 int n;
3944
3945 n = getgroups(MAX_GROUPS, grouplist);
3946 if (n < 0)
3947 posix_error();
3948 else {
3949 result = PyList_New(n);
3950 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003951 int i;
3952 for (i = 0; i < n; ++i) {
Christian Heimes217cfd12007-12-02 14:31:20 +00003953 PyObject *o = PyLong_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003954 if (o == NULL) {
3955 Py_DECREF(result);
3956 result = NULL;
3957 break;
3958 }
3959 PyList_SET_ITEM(result, i, o);
3960 }
3961 }
3962 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003963
Fred Drakec9680921999-12-13 16:37:25 +00003964 return result;
3965}
3966#endif
3967
Martin v. Löwis606edc12002-06-13 21:09:11 +00003968#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003969PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003970"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003971Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003972
3973static PyObject *
3974posix_getpgid(PyObject *self, PyObject *args)
3975{
3976 int pid, pgid;
3977 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3978 return NULL;
3979 pgid = getpgid(pid);
3980 if (pgid < 0)
3981 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00003982 return PyLong_FromLong((long)pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00003983}
3984#endif /* HAVE_GETPGID */
3985
3986
Guido van Rossumb6775db1994-08-01 11:34:53 +00003987#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003988PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003989"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003990Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003991
Barry Warsaw53699e91996-12-10 23:23:01 +00003992static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003993posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003994{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003995#ifdef GETPGRP_HAVE_ARG
Christian Heimes217cfd12007-12-02 14:31:20 +00003996 return PyLong_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003997#else /* GETPGRP_HAVE_ARG */
Christian Heimes217cfd12007-12-02 14:31:20 +00003998 return PyLong_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003999#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004000}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004001#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004002
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004003
Guido van Rossumb6775db1994-08-01 11:34:53 +00004004#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004005PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004006"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004007Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004008
Barry Warsaw53699e91996-12-10 23:23:01 +00004009static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004010posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004011{
Guido van Rossum64933891994-10-20 21:56:42 +00004012#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00004013 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004014#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004015 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004016#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00004017 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004018 Py_INCREF(Py_None);
4019 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004020}
4021
Guido van Rossumb6775db1994-08-01 11:34:53 +00004022#endif /* HAVE_SETPGRP */
4023
Guido van Rossumad0ee831995-03-01 10:34:45 +00004024#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004025PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004026"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004027Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004028
Barry Warsaw53699e91996-12-10 23:23:01 +00004029static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004030posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004031{
Christian Heimes217cfd12007-12-02 14:31:20 +00004032 return PyLong_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004033}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004034#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004036
Fred Drake12c6e2d1999-12-14 21:25:03 +00004037#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004038PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004039"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004040Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004041
4042static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004043posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004044{
Neal Norwitze241ce82003-02-17 18:17:05 +00004045 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00004046 char *name;
4047 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004048
Fred Drakea30680b2000-12-06 21:24:28 +00004049 errno = 0;
4050 name = getlogin();
4051 if (name == NULL) {
4052 if (errno)
4053 posix_error();
4054 else
4055 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00004056 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00004057 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00004058 else
Neal Norwitz93c56822007-08-26 07:10:06 +00004059 result = PyUnicode_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00004060 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004061
Fred Drake12c6e2d1999-12-14 21:25:03 +00004062 return result;
4063}
4064#endif
4065
Guido van Rossumad0ee831995-03-01 10:34:45 +00004066#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004067PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004068"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004069Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004070
Barry Warsaw53699e91996-12-10 23:23:01 +00004071static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004072posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004073{
Christian Heimes217cfd12007-12-02 14:31:20 +00004074 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004075}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004076#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004077
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004078
Guido van Rossumad0ee831995-03-01 10:34:45 +00004079#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004080PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004081"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004082Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004083
Barry Warsaw53699e91996-12-10 23:23:01 +00004084static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004085posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004086{
Christian Heimes292d3512008-02-03 16:51:08 +00004087 pid_t pid;
4088 int sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004089 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00004090 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004091#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004092 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4093 APIRET rc;
4094 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004095 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004096
4097 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4098 APIRET rc;
4099 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004100 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004101
4102 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004103 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004104#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00004105 if (kill(pid, sig) == -1)
4106 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004107#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004108 Py_INCREF(Py_None);
4109 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004110}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004111#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004112
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004113#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004114PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004115"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004116Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004117
4118static PyObject *
4119posix_killpg(PyObject *self, PyObject *args)
4120{
4121 int pgid, sig;
4122 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
4123 return NULL;
4124 if (killpg(pgid, sig) == -1)
4125 return posix_error();
4126 Py_INCREF(Py_None);
4127 return Py_None;
4128}
4129#endif
4130
Guido van Rossumc0125471996-06-28 18:55:32 +00004131#ifdef HAVE_PLOCK
4132
4133#ifdef HAVE_SYS_LOCK_H
4134#include <sys/lock.h>
4135#endif
4136
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004137PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004138"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004139Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004140
Barry Warsaw53699e91996-12-10 23:23:01 +00004141static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004142posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004143{
4144 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004145 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00004146 return NULL;
4147 if (plock(op) == -1)
4148 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004149 Py_INCREF(Py_None);
4150 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004151}
4152#endif
4153
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004154
Guido van Rossum3b066191991-06-04 19:40:25 +00004155
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004156
Guido van Rossumb6775db1994-08-01 11:34:53 +00004157#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004158PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004159"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004160Set the current process's user id.");
4161
Barry Warsaw53699e91996-12-10 23:23:01 +00004162static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004163posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004164{
4165 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004166 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004167 return NULL;
4168 if (setuid(uid) < 0)
4169 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004170 Py_INCREF(Py_None);
4171 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004172}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004173#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004174
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004175
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004176#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004177PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004178"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004179Set the current process's effective user id.");
4180
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004181static PyObject *
4182posix_seteuid (PyObject *self, PyObject *args)
4183{
4184 int euid;
4185 if (!PyArg_ParseTuple(args, "i", &euid)) {
4186 return NULL;
4187 } else if (seteuid(euid) < 0) {
4188 return posix_error();
4189 } else {
4190 Py_INCREF(Py_None);
4191 return Py_None;
4192 }
4193}
4194#endif /* HAVE_SETEUID */
4195
4196#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004197PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004198"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004199Set the current process's effective group id.");
4200
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004201static PyObject *
4202posix_setegid (PyObject *self, PyObject *args)
4203{
4204 int egid;
4205 if (!PyArg_ParseTuple(args, "i", &egid)) {
4206 return NULL;
4207 } else if (setegid(egid) < 0) {
4208 return posix_error();
4209 } else {
4210 Py_INCREF(Py_None);
4211 return Py_None;
4212 }
4213}
4214#endif /* HAVE_SETEGID */
4215
4216#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004217PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004218"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004219Set the current process's real and effective user ids.");
4220
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004221static PyObject *
4222posix_setreuid (PyObject *self, PyObject *args)
4223{
4224 int ruid, euid;
4225 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4226 return NULL;
4227 } else if (setreuid(ruid, euid) < 0) {
4228 return posix_error();
4229 } else {
4230 Py_INCREF(Py_None);
4231 return Py_None;
4232 }
4233}
4234#endif /* HAVE_SETREUID */
4235
4236#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004237PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004238"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004239Set the current process's real and effective group ids.");
4240
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004241static PyObject *
4242posix_setregid (PyObject *self, PyObject *args)
4243{
4244 int rgid, egid;
4245 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4246 return NULL;
4247 } else if (setregid(rgid, egid) < 0) {
4248 return posix_error();
4249 } else {
4250 Py_INCREF(Py_None);
4251 return Py_None;
4252 }
4253}
4254#endif /* HAVE_SETREGID */
4255
Guido van Rossumb6775db1994-08-01 11:34:53 +00004256#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004257PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004258"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004259Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004260
Barry Warsaw53699e91996-12-10 23:23:01 +00004261static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004262posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004263{
4264 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004265 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004266 return NULL;
4267 if (setgid(gid) < 0)
4268 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004269 Py_INCREF(Py_None);
4270 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004271}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004272#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004273
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004274#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004275PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004276"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004277Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004278
4279static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004280posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004281{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004282 int i, len;
4283 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004284
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004285 if (!PySequence_Check(groups)) {
4286 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4287 return NULL;
4288 }
4289 len = PySequence_Size(groups);
4290 if (len > MAX_GROUPS) {
4291 PyErr_SetString(PyExc_ValueError, "too many groups");
4292 return NULL;
4293 }
4294 for(i = 0; i < len; i++) {
4295 PyObject *elem;
4296 elem = PySequence_GetItem(groups, i);
4297 if (!elem)
4298 return NULL;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004299 if (!PyLong_Check(elem)) {
4300 PyErr_SetString(PyExc_TypeError,
4301 "groups must be integers");
4302 Py_DECREF(elem);
4303 return NULL;
4304 } else {
4305 unsigned long x = PyLong_AsUnsignedLong(elem);
4306 if (PyErr_Occurred()) {
4307 PyErr_SetString(PyExc_TypeError,
4308 "group id too big");
Georg Brandla13c2442005-11-22 19:30:31 +00004309 Py_DECREF(elem);
4310 return NULL;
Georg Brandla13c2442005-11-22 19:30:31 +00004311 }
Georg Brandla13c2442005-11-22 19:30:31 +00004312 grouplist[i] = x;
Guido van Rossumddefaf32007-01-14 03:31:43 +00004313 /* read back the value to see if it fitted in gid_t */
Georg Brandla13c2442005-11-22 19:30:31 +00004314 if (grouplist[i] != x) {
4315 PyErr_SetString(PyExc_TypeError,
4316 "group id too big");
4317 Py_DECREF(elem);
4318 return NULL;
4319 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004320 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004321 Py_DECREF(elem);
4322 }
4323
4324 if (setgroups(len, grouplist) < 0)
4325 return posix_error();
4326 Py_INCREF(Py_None);
4327 return Py_None;
4328}
4329#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004330
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004331#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4332static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004333wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004334{
4335 PyObject *result;
4336 static PyObject *struct_rusage;
4337
4338 if (pid == -1)
4339 return posix_error();
4340
4341 if (struct_rusage == NULL) {
Christian Heimes072c0f12008-01-03 23:01:04 +00004342 PyObject *m = PyImport_ImportModuleNoBlock("resource");
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004343 if (m == NULL)
4344 return NULL;
4345 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4346 Py_DECREF(m);
4347 if (struct_rusage == NULL)
4348 return NULL;
4349 }
4350
4351 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4352 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4353 if (!result)
4354 return NULL;
4355
4356#ifndef doubletime
4357#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4358#endif
4359
4360 PyStructSequence_SET_ITEM(result, 0,
4361 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4362 PyStructSequence_SET_ITEM(result, 1,
4363 PyFloat_FromDouble(doubletime(ru->ru_stime)));
4364#define SET_INT(result, index, value)\
Christian Heimes217cfd12007-12-02 14:31:20 +00004365 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004366 SET_INT(result, 2, ru->ru_maxrss);
4367 SET_INT(result, 3, ru->ru_ixrss);
4368 SET_INT(result, 4, ru->ru_idrss);
4369 SET_INT(result, 5, ru->ru_isrss);
4370 SET_INT(result, 6, ru->ru_minflt);
4371 SET_INT(result, 7, ru->ru_majflt);
4372 SET_INT(result, 8, ru->ru_nswap);
4373 SET_INT(result, 9, ru->ru_inblock);
4374 SET_INT(result, 10, ru->ru_oublock);
4375 SET_INT(result, 11, ru->ru_msgsnd);
4376 SET_INT(result, 12, ru->ru_msgrcv);
4377 SET_INT(result, 13, ru->ru_nsignals);
4378 SET_INT(result, 14, ru->ru_nvcsw);
4379 SET_INT(result, 15, ru->ru_nivcsw);
4380#undef SET_INT
4381
4382 if (PyErr_Occurred()) {
4383 Py_DECREF(result);
4384 return NULL;
4385 }
4386
4387 return Py_BuildValue("iiN", pid, status, result);
4388}
4389#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4390
4391#ifdef HAVE_WAIT3
4392PyDoc_STRVAR(posix_wait3__doc__,
4393"wait3(options) -> (pid, status, rusage)\n\n\
4394Wait for completion of a child process.");
4395
4396static PyObject *
4397posix_wait3(PyObject *self, PyObject *args)
4398{
Christian Heimes292d3512008-02-03 16:51:08 +00004399 pid_t pid;
4400 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004401 struct rusage ru;
4402 WAIT_TYPE status;
4403 WAIT_STATUS_INT(status) = 0;
4404
4405 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4406 return NULL;
4407
4408 Py_BEGIN_ALLOW_THREADS
4409 pid = wait3(&status, options, &ru);
4410 Py_END_ALLOW_THREADS
4411
4412 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4413}
4414#endif /* HAVE_WAIT3 */
4415
4416#ifdef HAVE_WAIT4
4417PyDoc_STRVAR(posix_wait4__doc__,
4418"wait4(pid, options) -> (pid, status, rusage)\n\n\
4419Wait for completion of a given child process.");
4420
4421static PyObject *
4422posix_wait4(PyObject *self, PyObject *args)
4423{
Christian Heimes292d3512008-02-03 16:51:08 +00004424 pid_t pid;
4425 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004426 struct rusage ru;
4427 WAIT_TYPE status;
4428 WAIT_STATUS_INT(status) = 0;
4429
4430 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
4431 return NULL;
4432
4433 Py_BEGIN_ALLOW_THREADS
4434 pid = wait4(pid, &status, options, &ru);
4435 Py_END_ALLOW_THREADS
4436
4437 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4438}
4439#endif /* HAVE_WAIT4 */
4440
Guido van Rossumb6775db1994-08-01 11:34:53 +00004441#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004442PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004443"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004444Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004445
Barry Warsaw53699e91996-12-10 23:23:01 +00004446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004447posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004448{
Christian Heimes292d3512008-02-03 16:51:08 +00004449 pid_t pid;
4450 int options;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004451 WAIT_TYPE status;
4452 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004453
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004454 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004455 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004456 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004457 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004458 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004459 if (pid == -1)
4460 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004461
4462 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004463}
4464
Tim Petersab034fa2002-02-01 11:27:43 +00004465#elif defined(HAVE_CWAIT)
4466
4467/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004468PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004469"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004470"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004471
4472static PyObject *
4473posix_waitpid(PyObject *self, PyObject *args)
4474{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004475 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004476 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004477
4478 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4479 return NULL;
4480 Py_BEGIN_ALLOW_THREADS
4481 pid = _cwait(&status, pid, options);
4482 Py_END_ALLOW_THREADS
4483 if (pid == -1)
4484 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004485
4486 /* shift the status left a byte so this is more like the POSIX waitpid */
4487 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004488}
4489#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004490
Guido van Rossumad0ee831995-03-01 10:34:45 +00004491#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004492PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004493"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004494Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004495
Barry Warsaw53699e91996-12-10 23:23:01 +00004496static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004497posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004498{
Christian Heimes292d3512008-02-03 16:51:08 +00004499 pid_t pid;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004500 WAIT_TYPE status;
4501 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004502
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004503 Py_BEGIN_ALLOW_THREADS
4504 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004505 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004506 if (pid == -1)
4507 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004508
4509 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004510}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004511#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004512
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004513
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004514PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004515"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004516Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004517
Barry Warsaw53699e91996-12-10 23:23:01 +00004518static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004519posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004520{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004521#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004522 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004523#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004524#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00004525 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004526#else
4527 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4528#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004529#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004530}
4531
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004532
Guido van Rossumb6775db1994-08-01 11:34:53 +00004533#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004534PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004535"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004536Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004537
Barry Warsaw53699e91996-12-10 23:23:01 +00004538static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004539posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004540{
Thomas Wouters89f507f2006-12-13 04:49:30 +00004541 PyObject* v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00004542 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004543 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004544 int n;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004545 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004546
4547 if (!PyArg_ParseTuple(args, "et:readlink",
4548 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004549 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004550 v = PySequence_GetItem(args, 0);
Neal Norwitzcda5c062007-08-12 17:09:36 +00004551 if (v == NULL) {
4552 PyMem_Free(path);
4553 return NULL;
4554 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004555
4556 if (PyUnicode_Check(v)) {
4557 arg_is_unicode = 1;
4558 }
4559 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004560
Barry Warsaw53699e91996-12-10 23:23:01 +00004561 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004562 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004563 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004564 if (n < 0)
Neal Norwitzfca70052007-08-12 16:56:02 +00004565 return posix_error_with_allocated_filename(path);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004566
Neal Norwitzfca70052007-08-12 16:56:02 +00004567 PyMem_Free(path);
Christian Heimes72b710a2008-05-26 13:28:38 +00004568 v = PyBytes_FromStringAndSize(buf, n);
Thomas Wouters89f507f2006-12-13 04:49:30 +00004569 if (arg_is_unicode) {
4570 PyObject *w;
4571
4572 w = PyUnicode_FromEncodedObject(v,
4573 Py_FileSystemDefaultEncoding,
4574 "strict");
4575 if (w != NULL) {
4576 Py_DECREF(v);
4577 v = w;
4578 }
4579 else {
Guido van Rossumf0af3e32008-10-02 18:55:37 +00004580 v = NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004581 }
4582 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004583 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004584}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004585#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004586
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004587
Guido van Rossumb6775db1994-08-01 11:34:53 +00004588#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004589PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004590"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004591Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004592
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004593static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004594posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004595{
Thomas Wouters477c8d52006-05-27 19:21:47 +00004596 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004597}
4598#endif /* HAVE_SYMLINK */
4599
4600
4601#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00004602#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4603static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004604system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004605{
4606 ULONG value = 0;
4607
4608 Py_BEGIN_ALLOW_THREADS
4609 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4610 Py_END_ALLOW_THREADS
4611
4612 return value;
4613}
4614
4615static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004616posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004617{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004618 /* Currently Only Uptime is Provided -- Others Later */
4619 return Py_BuildValue("ddddd",
4620 (double)0 /* t.tms_utime / HZ */,
4621 (double)0 /* t.tms_stime / HZ */,
4622 (double)0 /* t.tms_cutime / HZ */,
4623 (double)0 /* t.tms_cstime / HZ */,
4624 (double)system_uptime() / 1000);
4625}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004626#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00004627#define NEED_TICKS_PER_SECOND
4628static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00004629static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004630posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004631{
4632 struct tms t;
4633 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004634 errno = 0;
4635 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004636 if (c == (clock_t) -1)
4637 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004638 return Py_BuildValue("ddddd",
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00004639 (double)t.tms_utime / ticks_per_second,
4640 (double)t.tms_stime / ticks_per_second,
4641 (double)t.tms_cutime / ticks_per_second,
4642 (double)t.tms_cstime / ticks_per_second,
4643 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004644}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004645#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004646#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004647
4648
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004649#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004650#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004651static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004652posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004653{
4654 FILETIME create, exit, kernel, user;
4655 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004656 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004657 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4658 /* The fields of a FILETIME structure are the hi and lo part
4659 of a 64-bit value expressed in 100 nanosecond units.
4660 1e7 is one second in such units; 1e-7 the inverse.
4661 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4662 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004663 return Py_BuildValue(
4664 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004665 (double)(user.dwHighDateTime*429.4967296 +
4666 user.dwLowDateTime*1e-7),
Christian Heimes68f5fbe2008-02-14 08:27:37 +00004667 (double)(kernel.dwHighDateTime*429.4967296 +
4668 kernel.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004669 (double)0,
4670 (double)0,
4671 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004672}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004673#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004674
4675#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004676PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004677"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004678Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004679#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004680
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004681
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004682#ifdef HAVE_GETSID
4683PyDoc_STRVAR(posix_getsid__doc__,
4684"getsid(pid) -> sid\n\n\
4685Call the system call getsid().");
4686
4687static PyObject *
4688posix_getsid(PyObject *self, PyObject *args)
4689{
Christian Heimes292d3512008-02-03 16:51:08 +00004690 pid_t pid;
4691 int sid;
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004692 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
4693 return NULL;
4694 sid = getsid(pid);
4695 if (sid < 0)
4696 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004697 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00004698}
4699#endif /* HAVE_GETSID */
4700
4701
Guido van Rossumb6775db1994-08-01 11:34:53 +00004702#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004703PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004704"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004705Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004706
Barry Warsaw53699e91996-12-10 23:23:01 +00004707static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004708posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004709{
Guido van Rossum687dd131993-05-17 08:34:16 +00004710 if (setsid() < 0)
4711 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004712 Py_INCREF(Py_None);
4713 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004714}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004715#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004716
Guido van Rossumb6775db1994-08-01 11:34:53 +00004717#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004718PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004719"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004720Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004721
Barry Warsaw53699e91996-12-10 23:23:01 +00004722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004723posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004724{
Christian Heimes292d3512008-02-03 16:51:08 +00004725 pid_t pid;
4726 int pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004727 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004728 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004729 if (setpgid(pid, pgrp) < 0)
4730 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004731 Py_INCREF(Py_None);
4732 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004733}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004734#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004735
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004736
Guido van Rossumb6775db1994-08-01 11:34:53 +00004737#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004738PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004739"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004740Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004741
Barry Warsaw53699e91996-12-10 23:23:01 +00004742static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004743posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004744{
Christian Heimes15ebc882008-02-04 18:48:49 +00004745 int fd;
4746 pid_t pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004747 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004748 return NULL;
4749 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004750 if (pgid < 0)
4751 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004752 return PyLong_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004753}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004754#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004755
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004756
Guido van Rossumb6775db1994-08-01 11:34:53 +00004757#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004758PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004759"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004760Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004761
Barry Warsaw53699e91996-12-10 23:23:01 +00004762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004763posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004764{
4765 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004766 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004767 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004768 if (tcsetpgrp(fd, pgid) < 0)
4769 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004770 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004771 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004772}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004773#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004774
Guido van Rossum687dd131993-05-17 08:34:16 +00004775/* Functions acting on file descriptors */
4776
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004777PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004778"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004779Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004780
Barry Warsaw53699e91996-12-10 23:23:01 +00004781static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004782posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004783{
Mark Hammondef8b6542001-05-13 08:04:26 +00004784 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004785 int flag;
4786 int mode = 0777;
4787 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004788
4789#ifdef MS_WINDOWS
4790 if (unicode_file_names()) {
4791 PyUnicodeObject *po;
4792 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4793 Py_BEGIN_ALLOW_THREADS
4794 /* PyUnicode_AS_UNICODE OK without thread
4795 lock as it is a simple dereference. */
4796 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4797 Py_END_ALLOW_THREADS
4798 if (fd < 0)
4799 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004800 return PyLong_FromLong((long)fd);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004801 }
4802 /* Drop the argument parsing error as narrow strings
4803 are also valid. */
4804 PyErr_Clear();
4805 }
4806#endif
4807
Tim Peters5aa91602002-01-30 05:46:57 +00004808 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004809 Py_FileSystemDefaultEncoding, &file,
4810 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004811 return NULL;
4812
Barry Warsaw53699e91996-12-10 23:23:01 +00004813 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004814 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004815 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004816 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004817 return posix_error_with_allocated_filename(file);
4818 PyMem_Free(file);
Christian Heimes217cfd12007-12-02 14:31:20 +00004819 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004820}
4821
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004822
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004823PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004824"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004825Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004826
Barry Warsaw53699e91996-12-10 23:23:01 +00004827static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004828posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004829{
4830 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004831 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004832 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004833 if (!_PyVerify_fd(fd))
4834 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004835 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004836 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004837 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004838 if (res < 0)
4839 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004840 Py_INCREF(Py_None);
4841 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004842}
4843
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004844
Christian Heimesfdab48e2008-01-20 09:06:41 +00004845PyDoc_STRVAR(posix_closerange__doc__,
4846"closerange(fd_low, fd_high)\n\n\
4847Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
4848
4849static PyObject *
4850posix_closerange(PyObject *self, PyObject *args)
4851{
4852 int fd_from, fd_to, i;
4853 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
4854 return NULL;
4855 Py_BEGIN_ALLOW_THREADS
4856 for (i = fd_from; i < fd_to; i++)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004857 if (_PyVerify_fd(i))
4858 close(i);
Christian Heimesfdab48e2008-01-20 09:06:41 +00004859 Py_END_ALLOW_THREADS
4860 Py_RETURN_NONE;
4861}
4862
4863
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004864PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004865"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004866Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004867
Barry Warsaw53699e91996-12-10 23:23:01 +00004868static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004869posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004870{
4871 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004872 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004873 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004874 if (!_PyVerify_fd(fd))
4875 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004876 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004877 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004878 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004879 if (fd < 0)
4880 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00004881 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004882}
4883
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004884
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004885PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00004886"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004887Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004888
Barry Warsaw53699e91996-12-10 23:23:01 +00004889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004890posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004891{
4892 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004893 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004894 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004895 if (!_PyVerify_fd_dup2(fd, fd2))
4896 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004897 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004898 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004899 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004900 if (res < 0)
4901 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004902 Py_INCREF(Py_None);
4903 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004904}
4905
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004906
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004907PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004908"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004909Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004910
Barry Warsaw53699e91996-12-10 23:23:01 +00004911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004912posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004913{
4914 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004915#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00004916 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004917#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004918 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004919#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004920 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004921 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004922 return NULL;
4923#ifdef SEEK_SET
4924 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4925 switch (how) {
4926 case 0: how = SEEK_SET; break;
4927 case 1: how = SEEK_CUR; break;
4928 case 2: how = SEEK_END; break;
4929 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004930#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004931
4932#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00004933 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004934#else
4935 pos = PyLong_Check(posobj) ?
Christian Heimes217cfd12007-12-02 14:31:20 +00004936 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004937#endif
4938 if (PyErr_Occurred())
4939 return NULL;
4940
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004941 if (!_PyVerify_fd(fd))
4942 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004943 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004944#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004945 res = _lseeki64(fd, pos, how);
4946#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004947 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004948#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004949 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004950 if (res < 0)
4951 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004952
4953#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00004954 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004955#else
4956 return PyLong_FromLongLong(res);
4957#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004958}
4959
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004960
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004961PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004962"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004963Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004964
Barry Warsaw53699e91996-12-10 23:23:01 +00004965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004966posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004967{
Guido van Rossum572dbf82007-04-27 23:53:51 +00004968 int fd, size;
4969 Py_ssize_t n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004970 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004971 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004972 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00004973 if (size < 0) {
4974 errno = EINVAL;
4975 return posix_error();
4976 }
Christian Heimes72b710a2008-05-26 13:28:38 +00004977 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004978 if (buffer == NULL)
4979 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00004980 if (!_PyVerify_fd(fd))
4981 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004982 Py_BEGIN_ALLOW_THREADS
Christian Heimes72b710a2008-05-26 13:28:38 +00004983 n = read(fd, PyBytes_AS_STRING(buffer), size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004984 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004985 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004986 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004987 return posix_error();
4988 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004989 if (n != size)
Christian Heimes72b710a2008-05-26 13:28:38 +00004990 _PyBytes_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004991 return buffer;
4992}
4993
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004994
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004995PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004996"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004997Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004998
Barry Warsaw53699e91996-12-10 23:23:01 +00004999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005000posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005001{
Martin v. Löwis423be952008-08-13 15:53:07 +00005002 Py_buffer pbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005003 int fd;
5004 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005005
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +00005006 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
Guido van Rossum687dd131993-05-17 08:34:16 +00005007 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005008 if (!_PyVerify_fd(fd))
5009 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005010 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis423be952008-08-13 15:53:07 +00005011 size = write(fd, pbuf.buf, (size_t)pbuf.len);
Barry Warsaw53699e91996-12-10 23:23:01 +00005012 Py_END_ALLOW_THREADS
Martin v. Löwis423be952008-08-13 15:53:07 +00005013 PyBuffer_Release(&pbuf);
Guido van Rossum687dd131993-05-17 08:34:16 +00005014 if (size < 0)
5015 return posix_error();
Christian Heimes217cfd12007-12-02 14:31:20 +00005016 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005017}
5018
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005019
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005020PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005021"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005022Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005023
Barry Warsaw53699e91996-12-10 23:23:01 +00005024static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005025posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005026{
5027 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005028 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005029 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005030 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005031 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005032#ifdef __VMS
5033 /* on OpenVMS we must ensure that all bytes are written to the file */
5034 fsync(fd);
5035#endif
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005036 if (!_PyVerify_fd(fd))
5037 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005038 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005039 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005040 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005041 if (res != 0) {
5042#ifdef MS_WINDOWS
5043 return win32_error("fstat", NULL);
5044#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005045 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005046#endif
5047 }
Tim Peters5aa91602002-01-30 05:46:57 +00005048
Martin v. Löwis14694662006-02-03 12:54:16 +00005049 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005050}
5051
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005052PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005053"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005054Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005055connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005056
5057static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005058posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005059{
5060 int fd;
5061 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5062 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00005063 if (!_PyVerify_fd(fd))
5064 return PyBool_FromLong(0);
Fred Drake106c1a02002-04-23 15:58:02 +00005065 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005066}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005067
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005068#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005069PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005070"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005071Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005072
Barry Warsaw53699e91996-12-10 23:23:01 +00005073static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005074posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005075{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005076#if defined(PYOS_OS2)
5077 HFILE read, write;
5078 APIRET rc;
5079
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005080 Py_BEGIN_ALLOW_THREADS
5081 rc = DosCreatePipe( &read, &write, 4096);
5082 Py_END_ALLOW_THREADS
5083 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005084 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005085
5086 return Py_BuildValue("(ii)", read, write);
5087#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005088#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005089 int fds[2];
5090 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005091 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005092 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005093 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005094 if (res != 0)
5095 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005096 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005097#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005098 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005099 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005100 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005101 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005102 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005103 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005104 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005105 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005106 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5107 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005108 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005109#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005110#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005111}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005112#endif /* HAVE_PIPE */
5113
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005114
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005115#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005116PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005117"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005118Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005119
Barry Warsaw53699e91996-12-10 23:23:01 +00005120static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005121posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005122{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005123 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005124 int mode = 0666;
5125 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005126 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005127 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005128 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005129 res = mkfifo(filename, mode);
5130 Py_END_ALLOW_THREADS
5131 if (res < 0)
5132 return posix_error();
5133 Py_INCREF(Py_None);
5134 return Py_None;
5135}
5136#endif
5137
5138
Neal Norwitz11690112002-07-30 01:08:28 +00005139#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005140PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005141"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005142Create a filesystem node (file, device special file or named pipe)\n\
5143named filename. mode specifies both the permissions to use and the\n\
5144type of node to be created, being combined (bitwise OR) with one of\n\
5145S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005146device defines the newly created device special file (probably using\n\
5147os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005148
5149
5150static PyObject *
5151posix_mknod(PyObject *self, PyObject *args)
5152{
5153 char *filename;
5154 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005155 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005156 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005157 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005158 return NULL;
5159 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005160 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005161 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005162 if (res < 0)
5163 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005164 Py_INCREF(Py_None);
5165 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005166}
5167#endif
5168
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005169#ifdef HAVE_DEVICE_MACROS
5170PyDoc_STRVAR(posix_major__doc__,
5171"major(device) -> major number\n\
5172Extracts a device major number from a raw device number.");
5173
5174static PyObject *
5175posix_major(PyObject *self, PyObject *args)
5176{
5177 int device;
5178 if (!PyArg_ParseTuple(args, "i:major", &device))
5179 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005180 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005181}
5182
5183PyDoc_STRVAR(posix_minor__doc__,
5184"minor(device) -> minor number\n\
5185Extracts a device minor number from a raw device number.");
5186
5187static PyObject *
5188posix_minor(PyObject *self, PyObject *args)
5189{
5190 int device;
5191 if (!PyArg_ParseTuple(args, "i:minor", &device))
5192 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005193 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005194}
5195
5196PyDoc_STRVAR(posix_makedev__doc__,
5197"makedev(major, minor) -> device number\n\
5198Composes a raw device number from the major and minor device numbers.");
5199
5200static PyObject *
5201posix_makedev(PyObject *self, PyObject *args)
5202{
5203 int major, minor;
5204 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5205 return NULL;
Christian Heimes217cfd12007-12-02 14:31:20 +00005206 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005207}
5208#endif /* device macros */
5209
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005210
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005211#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005212PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005213"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005214Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005215
Barry Warsaw53699e91996-12-10 23:23:01 +00005216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005217posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005218{
5219 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005220 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005221 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005222 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005223
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005224 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005225 return NULL;
5226
5227#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005228 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005229#else
5230 length = PyLong_Check(lenobj) ?
Christian Heimes217cfd12007-12-02 14:31:20 +00005231 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005232#endif
5233 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005234 return NULL;
5235
Barry Warsaw53699e91996-12-10 23:23:01 +00005236 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005237 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005238 Py_END_ALLOW_THREADS
Benjamin Peterson9053d752009-01-19 17:53:36 +00005239 if (res < 0)
5240 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005241 Py_INCREF(Py_None);
5242 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005243}
5244#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005245
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005246#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005247PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005248"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005249Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005250
Fred Drake762e2061999-08-26 17:23:54 +00005251/* Save putenv() parameters as values here, so we can collect them when they
5252 * get re-set with another call for the same key. */
5253static PyObject *posix_putenv_garbage;
5254
Tim Peters5aa91602002-01-30 05:46:57 +00005255static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005256posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005257{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005258#ifdef MS_WINDOWS
5259 wchar_t *s1, *s2;
5260 wchar_t *newenv;
5261#else
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005262 char *s1, *s2;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005263 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005264#endif
Fred Drake762e2061999-08-26 17:23:54 +00005265 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005266 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005267
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005268 if (!PyArg_ParseTuple(args,
5269#ifdef MS_WINDOWS
5270 "uu:putenv",
5271#else
5272 "ss:putenv",
5273#endif
5274 &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005275 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005276
5277#if defined(PYOS_OS2)
5278 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5279 APIRET rc;
5280
Guido van Rossumd48f2521997-12-05 22:19:34 +00005281 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5282 if (rc != NO_ERROR)
5283 return os2_error(rc);
5284
5285 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5286 APIRET rc;
5287
Guido van Rossumd48f2521997-12-05 22:19:34 +00005288 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5289 if (rc != NO_ERROR)
5290 return os2_error(rc);
5291 } else {
5292#endif
Fred Drake762e2061999-08-26 17:23:54 +00005293 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005294 /* len includes space for a trailing \0; the size arg to
Christian Heimes72b710a2008-05-26 13:28:38 +00005295 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005296#ifdef MS_WINDOWS
5297 len = wcslen(s1) + wcslen(s2) + 2;
5298 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
5299#else
5300 len = strlen(s1) + strlen(s2) + 2;
Christian Heimes72b710a2008-05-26 13:28:38 +00005301 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005302#endif
Fred Drake762e2061999-08-26 17:23:54 +00005303 if (newstr == NULL)
5304 return PyErr_NoMemory();
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005305#ifdef MS_WINDOWS
5306 newenv = PyUnicode_AsUnicode(newstr);
5307 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5308 if (_wputenv(newenv)) {
5309 Py_DECREF(newstr);
5310 posix_error();
5311 return NULL;
5312 }
5313#else
Christian Heimes72b710a2008-05-26 13:28:38 +00005314 newenv = PyBytes_AS_STRING(newstr);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005315 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5316 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005317 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005318 posix_error();
5319 return NULL;
5320 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005321#endif
Fred Drake762e2061999-08-26 17:23:54 +00005322 /* Install the first arg and newstr in posix_putenv_garbage;
5323 * this will cause previous value to be collected. This has to
5324 * happen after the real putenv() call because the old value
5325 * was still accessible until then. */
5326 if (PyDict_SetItem(posix_putenv_garbage,
5327 PyTuple_GET_ITEM(args, 0), newstr)) {
5328 /* really not much we can do; just leak */
5329 PyErr_Clear();
5330 }
5331 else {
5332 Py_DECREF(newstr);
5333 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005334
5335#if defined(PYOS_OS2)
5336 }
5337#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005338 Py_INCREF(Py_None);
5339 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005340}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005341#endif /* putenv */
5342
Guido van Rossumc524d952001-10-19 01:31:59 +00005343#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005344PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005345"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005346Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005347
5348static PyObject *
5349posix_unsetenv(PyObject *self, PyObject *args)
5350{
5351 char *s1;
5352
5353 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5354 return NULL;
5355
5356 unsetenv(s1);
5357
5358 /* Remove the key from posix_putenv_garbage;
5359 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005360 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005361 * old value was still accessible until then.
5362 */
5363 if (PyDict_DelItem(posix_putenv_garbage,
5364 PyTuple_GET_ITEM(args, 0))) {
5365 /* really not much we can do; just leak */
5366 PyErr_Clear();
5367 }
5368
5369 Py_INCREF(Py_None);
5370 return Py_None;
5371}
5372#endif /* unsetenv */
5373
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005374PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005375"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005376Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005377
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005378static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005379posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005380{
5381 int code;
5382 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005383 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005384 return NULL;
5385 message = strerror(code);
5386 if (message == NULL) {
5387 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005388 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005389 return NULL;
5390 }
Neal Norwitz93c56822007-08-26 07:10:06 +00005391 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00005392}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005393
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005394
Guido van Rossumc9641791998-08-04 15:26:23 +00005395#ifdef HAVE_SYS_WAIT_H
5396
Fred Drake106c1a02002-04-23 15:58:02 +00005397#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005398PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005399"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005400Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005401
5402static PyObject *
5403posix_WCOREDUMP(PyObject *self, PyObject *args)
5404{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005405 WAIT_TYPE status;
5406 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005407
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005408 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005409 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005410
5411 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005412}
5413#endif /* WCOREDUMP */
5414
5415#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005416PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005417"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005418Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005419job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005420
5421static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005422posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005423{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005424 WAIT_TYPE status;
5425 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00005426
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005427 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00005428 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005429
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005430 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005431}
5432#endif /* WIFCONTINUED */
5433
Guido van Rossumc9641791998-08-04 15:26:23 +00005434#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005435PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005436"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005437Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005438
5439static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005440posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005441{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005442 WAIT_TYPE status;
5443 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005444
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005445 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005446 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005447
Fred Drake106c1a02002-04-23 15:58:02 +00005448 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005449}
5450#endif /* WIFSTOPPED */
5451
5452#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005453PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005454"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005455Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005456
5457static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005458posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005459{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005460 WAIT_TYPE status;
5461 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005462
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005463 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005464 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005465
Fred Drake106c1a02002-04-23 15:58:02 +00005466 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005467}
5468#endif /* WIFSIGNALED */
5469
5470#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005471PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005472"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005473Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005474system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005475
5476static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005477posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005478{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005479 WAIT_TYPE status;
5480 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005481
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005482 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005483 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005484
Fred Drake106c1a02002-04-23 15:58:02 +00005485 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00005486}
5487#endif /* WIFEXITED */
5488
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005489#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005490PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005491"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005492Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005493
5494static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005495posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005496{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005497 WAIT_TYPE status;
5498 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005499
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005500 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005501 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005502
Guido van Rossumc9641791998-08-04 15:26:23 +00005503 return Py_BuildValue("i", WEXITSTATUS(status));
5504}
5505#endif /* WEXITSTATUS */
5506
5507#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005508PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005509"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005510Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005511value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005512
5513static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005514posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005515{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005516 WAIT_TYPE status;
5517 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005518
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005519 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005520 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005521
Guido van Rossumc9641791998-08-04 15:26:23 +00005522 return Py_BuildValue("i", WTERMSIG(status));
5523}
5524#endif /* WTERMSIG */
5525
5526#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005527PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005528"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005529Return the signal that stopped the process that provided\n\
5530the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005531
5532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005533posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005534{
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005535 WAIT_TYPE status;
5536 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005537
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005538 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00005539 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005540
Guido van Rossumc9641791998-08-04 15:26:23 +00005541 return Py_BuildValue("i", WSTOPSIG(status));
5542}
5543#endif /* WSTOPSIG */
5544
5545#endif /* HAVE_SYS_WAIT_H */
5546
5547
Thomas Wouters477c8d52006-05-27 19:21:47 +00005548#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005549#ifdef _SCO_DS
5550/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5551 needed definitions in sys/statvfs.h */
5552#define _SVID3
5553#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005554#include <sys/statvfs.h>
5555
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005556static PyObject*
5557_pystatvfs_fromstructstatvfs(struct statvfs st) {
5558 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5559 if (v == NULL)
5560 return NULL;
5561
5562#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +00005563 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5564 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5565 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
5566 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
5567 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
5568 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
5569 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
5570 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
5571 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5572 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005573#else
Christian Heimes217cfd12007-12-02 14:31:20 +00005574 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5575 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005576 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005577 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005578 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005579 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005580 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005581 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005582 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005583 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005584 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005585 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005586 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005587 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Christian Heimes217cfd12007-12-02 14:31:20 +00005588 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5589 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005590#endif
5591
5592 return v;
5593}
5594
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005595PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005596"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005597Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005598
5599static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005600posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005601{
5602 int fd, res;
5603 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005604
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005605 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005606 return NULL;
5607 Py_BEGIN_ALLOW_THREADS
5608 res = fstatvfs(fd, &st);
5609 Py_END_ALLOW_THREADS
5610 if (res != 0)
5611 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005612
5613 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005614}
Thomas Wouters477c8d52006-05-27 19:21:47 +00005615#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005616
5617
Thomas Wouters477c8d52006-05-27 19:21:47 +00005618#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005619#include <sys/statvfs.h>
5620
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005621PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005622"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005623Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005624
5625static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005626posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005627{
5628 char *path;
5629 int res;
5630 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005631 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005632 return NULL;
5633 Py_BEGIN_ALLOW_THREADS
5634 res = statvfs(path, &st);
5635 Py_END_ALLOW_THREADS
5636 if (res != 0)
5637 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005638
5639 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005640}
5641#endif /* HAVE_STATVFS */
5642
Fred Drakec9680921999-12-13 16:37:25 +00005643/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5644 * It maps strings representing configuration variable names to
5645 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005646 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005647 * rarely-used constants. There are three separate tables that use
5648 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005649 *
5650 * This code is always included, even if none of the interfaces that
5651 * need it are included. The #if hackery needed to avoid it would be
5652 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005653 */
5654struct constdef {
5655 char *name;
5656 long value;
5657};
5658
Fred Drake12c6e2d1999-12-14 21:25:03 +00005659static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005660conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005661 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005662{
Christian Heimes217cfd12007-12-02 14:31:20 +00005663 if (PyLong_Check(arg)) {
5664 *valuep = PyLong_AS_LONG(arg);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005665 return 1;
5666 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00005667 else {
Fred Drake12c6e2d1999-12-14 21:25:03 +00005668 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005669 size_t lo = 0;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005670 size_t mid;
Fred Drake699f3522000-06-29 21:12:41 +00005671 size_t hi = tablesize;
5672 int cmp;
Guido van Rossumbce56a62007-05-10 18:04:33 +00005673 const char *confname;
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005674 if (!PyUnicode_Check(arg)) {
Guido van Rossumbce56a62007-05-10 18:04:33 +00005675 PyErr_SetString(PyExc_TypeError,
5676 "configuration names must be strings or integers");
5677 return 0;
5678 }
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00005679 confname = _PyUnicode_AsString(arg);
Guido van Rossum7d5baac2007-08-27 23:24:46 +00005680 if (confname == NULL)
5681 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005682 while (lo < hi) {
5683 mid = (lo + hi) / 2;
5684 cmp = strcmp(confname, table[mid].name);
5685 if (cmp < 0)
5686 hi = mid;
5687 else if (cmp > 0)
5688 lo = mid + 1;
5689 else {
5690 *valuep = table[mid].value;
5691 return 1;
5692 }
5693 }
5694 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Guido van Rossumbce56a62007-05-10 18:04:33 +00005695 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005696 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00005697}
5698
5699
5700#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5701static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005702#ifdef _PC_ABI_AIO_XFER_MAX
5703 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5704#endif
5705#ifdef _PC_ABI_ASYNC_IO
5706 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5707#endif
Fred Drakec9680921999-12-13 16:37:25 +00005708#ifdef _PC_ASYNC_IO
5709 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5710#endif
5711#ifdef _PC_CHOWN_RESTRICTED
5712 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5713#endif
5714#ifdef _PC_FILESIZEBITS
5715 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5716#endif
5717#ifdef _PC_LAST
5718 {"PC_LAST", _PC_LAST},
5719#endif
5720#ifdef _PC_LINK_MAX
5721 {"PC_LINK_MAX", _PC_LINK_MAX},
5722#endif
5723#ifdef _PC_MAX_CANON
5724 {"PC_MAX_CANON", _PC_MAX_CANON},
5725#endif
5726#ifdef _PC_MAX_INPUT
5727 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5728#endif
5729#ifdef _PC_NAME_MAX
5730 {"PC_NAME_MAX", _PC_NAME_MAX},
5731#endif
5732#ifdef _PC_NO_TRUNC
5733 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5734#endif
5735#ifdef _PC_PATH_MAX
5736 {"PC_PATH_MAX", _PC_PATH_MAX},
5737#endif
5738#ifdef _PC_PIPE_BUF
5739 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5740#endif
5741#ifdef _PC_PRIO_IO
5742 {"PC_PRIO_IO", _PC_PRIO_IO},
5743#endif
5744#ifdef _PC_SOCK_MAXBUF
5745 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5746#endif
5747#ifdef _PC_SYNC_IO
5748 {"PC_SYNC_IO", _PC_SYNC_IO},
5749#endif
5750#ifdef _PC_VDISABLE
5751 {"PC_VDISABLE", _PC_VDISABLE},
5752#endif
5753};
5754
Fred Drakec9680921999-12-13 16:37:25 +00005755static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005756conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005757{
5758 return conv_confname(arg, valuep, posix_constants_pathconf,
5759 sizeof(posix_constants_pathconf)
5760 / sizeof(struct constdef));
5761}
5762#endif
5763
5764#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005765PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005766"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005767Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005768If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005769
5770static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005771posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005772{
5773 PyObject *result = NULL;
5774 int name, fd;
5775
Fred Drake12c6e2d1999-12-14 21:25:03 +00005776 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5777 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005778 long limit;
5779
5780 errno = 0;
5781 limit = fpathconf(fd, name);
5782 if (limit == -1 && errno != 0)
5783 posix_error();
5784 else
Christian Heimes217cfd12007-12-02 14:31:20 +00005785 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005786 }
5787 return result;
5788}
5789#endif
5790
5791
5792#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005793PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005794"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005795Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005796If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005797
5798static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005799posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005800{
5801 PyObject *result = NULL;
5802 int name;
5803 char *path;
5804
5805 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5806 conv_path_confname, &name)) {
5807 long limit;
5808
5809 errno = 0;
5810 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005811 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005812 if (errno == EINVAL)
5813 /* could be a path or name problem */
5814 posix_error();
5815 else
5816 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005817 }
Fred Drakec9680921999-12-13 16:37:25 +00005818 else
Christian Heimes217cfd12007-12-02 14:31:20 +00005819 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00005820 }
5821 return result;
5822}
5823#endif
5824
5825#ifdef HAVE_CONFSTR
5826static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005827#ifdef _CS_ARCHITECTURE
5828 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5829#endif
5830#ifdef _CS_HOSTNAME
5831 {"CS_HOSTNAME", _CS_HOSTNAME},
5832#endif
5833#ifdef _CS_HW_PROVIDER
5834 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5835#endif
5836#ifdef _CS_HW_SERIAL
5837 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5838#endif
5839#ifdef _CS_INITTAB_NAME
5840 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5841#endif
Fred Drakec9680921999-12-13 16:37:25 +00005842#ifdef _CS_LFS64_CFLAGS
5843 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5844#endif
5845#ifdef _CS_LFS64_LDFLAGS
5846 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5847#endif
5848#ifdef _CS_LFS64_LIBS
5849 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5850#endif
5851#ifdef _CS_LFS64_LINTFLAGS
5852 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5853#endif
5854#ifdef _CS_LFS_CFLAGS
5855 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5856#endif
5857#ifdef _CS_LFS_LDFLAGS
5858 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5859#endif
5860#ifdef _CS_LFS_LIBS
5861 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5862#endif
5863#ifdef _CS_LFS_LINTFLAGS
5864 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5865#endif
Fred Draked86ed291999-12-15 15:34:33 +00005866#ifdef _CS_MACHINE
5867 {"CS_MACHINE", _CS_MACHINE},
5868#endif
Fred Drakec9680921999-12-13 16:37:25 +00005869#ifdef _CS_PATH
5870 {"CS_PATH", _CS_PATH},
5871#endif
Fred Draked86ed291999-12-15 15:34:33 +00005872#ifdef _CS_RELEASE
5873 {"CS_RELEASE", _CS_RELEASE},
5874#endif
5875#ifdef _CS_SRPC_DOMAIN
5876 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5877#endif
5878#ifdef _CS_SYSNAME
5879 {"CS_SYSNAME", _CS_SYSNAME},
5880#endif
5881#ifdef _CS_VERSION
5882 {"CS_VERSION", _CS_VERSION},
5883#endif
Fred Drakec9680921999-12-13 16:37:25 +00005884#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5885 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5886#endif
5887#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5888 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5889#endif
5890#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5891 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5892#endif
5893#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5894 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5895#endif
5896#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5897 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5898#endif
5899#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5900 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5901#endif
5902#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5903 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5904#endif
5905#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5906 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5907#endif
5908#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5909 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5910#endif
5911#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5912 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5913#endif
5914#ifdef _CS_XBS5_LP64_OFF64_LIBS
5915 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5916#endif
5917#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5918 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5919#endif
5920#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5921 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5922#endif
5923#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5924 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5925#endif
5926#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5927 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5928#endif
5929#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5930 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5931#endif
Fred Draked86ed291999-12-15 15:34:33 +00005932#ifdef _MIPS_CS_AVAIL_PROCESSORS
5933 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5934#endif
5935#ifdef _MIPS_CS_BASE
5936 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5937#endif
5938#ifdef _MIPS_CS_HOSTID
5939 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5940#endif
5941#ifdef _MIPS_CS_HW_NAME
5942 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5943#endif
5944#ifdef _MIPS_CS_NUM_PROCESSORS
5945 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5946#endif
5947#ifdef _MIPS_CS_OSREL_MAJ
5948 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5949#endif
5950#ifdef _MIPS_CS_OSREL_MIN
5951 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5952#endif
5953#ifdef _MIPS_CS_OSREL_PATCH
5954 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5955#endif
5956#ifdef _MIPS_CS_OS_NAME
5957 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5958#endif
5959#ifdef _MIPS_CS_OS_PROVIDER
5960 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5961#endif
5962#ifdef _MIPS_CS_PROCESSORS
5963 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5964#endif
5965#ifdef _MIPS_CS_SERIAL
5966 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5967#endif
5968#ifdef _MIPS_CS_VENDOR
5969 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5970#endif
Fred Drakec9680921999-12-13 16:37:25 +00005971};
5972
5973static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005974conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005975{
5976 return conv_confname(arg, valuep, posix_constants_confstr,
5977 sizeof(posix_constants_confstr)
5978 / sizeof(struct constdef));
5979}
5980
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005981PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005982"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005983Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005984
5985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005986posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005987{
5988 PyObject *result = NULL;
5989 int name;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005990 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00005991
5992 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005993 int len;
Fred Drakec9680921999-12-13 16:37:25 +00005994
Fred Drakec9680921999-12-13 16:37:25 +00005995 errno = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005996 len = confstr(name, buffer, sizeof(buffer));
5997 if (len == 0) {
5998 if (errno) {
5999 posix_error();
6000 }
6001 else {
6002 result = Py_None;
6003 Py_INCREF(Py_None);
6004 }
Fred Drakec9680921999-12-13 16:37:25 +00006005 }
6006 else {
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006007 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz93c56822007-08-26 07:10:06 +00006008 result = PyUnicode_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006009 if (result != NULL)
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +00006010 confstr(name, _PyUnicode_AsString(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00006011 }
6012 else
Neal Norwitz93c56822007-08-26 07:10:06 +00006013 result = PyUnicode_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006014 }
6015 }
6016 return result;
6017}
6018#endif
6019
6020
6021#ifdef HAVE_SYSCONF
6022static struct constdef posix_constants_sysconf[] = {
6023#ifdef _SC_2_CHAR_TERM
6024 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6025#endif
6026#ifdef _SC_2_C_BIND
6027 {"SC_2_C_BIND", _SC_2_C_BIND},
6028#endif
6029#ifdef _SC_2_C_DEV
6030 {"SC_2_C_DEV", _SC_2_C_DEV},
6031#endif
6032#ifdef _SC_2_C_VERSION
6033 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6034#endif
6035#ifdef _SC_2_FORT_DEV
6036 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6037#endif
6038#ifdef _SC_2_FORT_RUN
6039 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6040#endif
6041#ifdef _SC_2_LOCALEDEF
6042 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6043#endif
6044#ifdef _SC_2_SW_DEV
6045 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6046#endif
6047#ifdef _SC_2_UPE
6048 {"SC_2_UPE", _SC_2_UPE},
6049#endif
6050#ifdef _SC_2_VERSION
6051 {"SC_2_VERSION", _SC_2_VERSION},
6052#endif
Fred Draked86ed291999-12-15 15:34:33 +00006053#ifdef _SC_ABI_ASYNCHRONOUS_IO
6054 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6055#endif
6056#ifdef _SC_ACL
6057 {"SC_ACL", _SC_ACL},
6058#endif
Fred Drakec9680921999-12-13 16:37:25 +00006059#ifdef _SC_AIO_LISTIO_MAX
6060 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6061#endif
Fred Drakec9680921999-12-13 16:37:25 +00006062#ifdef _SC_AIO_MAX
6063 {"SC_AIO_MAX", _SC_AIO_MAX},
6064#endif
6065#ifdef _SC_AIO_PRIO_DELTA_MAX
6066 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6067#endif
6068#ifdef _SC_ARG_MAX
6069 {"SC_ARG_MAX", _SC_ARG_MAX},
6070#endif
6071#ifdef _SC_ASYNCHRONOUS_IO
6072 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6073#endif
6074#ifdef _SC_ATEXIT_MAX
6075 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6076#endif
Fred Draked86ed291999-12-15 15:34:33 +00006077#ifdef _SC_AUDIT
6078 {"SC_AUDIT", _SC_AUDIT},
6079#endif
Fred Drakec9680921999-12-13 16:37:25 +00006080#ifdef _SC_AVPHYS_PAGES
6081 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6082#endif
6083#ifdef _SC_BC_BASE_MAX
6084 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6085#endif
6086#ifdef _SC_BC_DIM_MAX
6087 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6088#endif
6089#ifdef _SC_BC_SCALE_MAX
6090 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6091#endif
6092#ifdef _SC_BC_STRING_MAX
6093 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6094#endif
Fred Draked86ed291999-12-15 15:34:33 +00006095#ifdef _SC_CAP
6096 {"SC_CAP", _SC_CAP},
6097#endif
Fred Drakec9680921999-12-13 16:37:25 +00006098#ifdef _SC_CHARCLASS_NAME_MAX
6099 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6100#endif
6101#ifdef _SC_CHAR_BIT
6102 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6103#endif
6104#ifdef _SC_CHAR_MAX
6105 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6106#endif
6107#ifdef _SC_CHAR_MIN
6108 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6109#endif
6110#ifdef _SC_CHILD_MAX
6111 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6112#endif
6113#ifdef _SC_CLK_TCK
6114 {"SC_CLK_TCK", _SC_CLK_TCK},
6115#endif
6116#ifdef _SC_COHER_BLKSZ
6117 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6118#endif
6119#ifdef _SC_COLL_WEIGHTS_MAX
6120 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6121#endif
6122#ifdef _SC_DCACHE_ASSOC
6123 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6124#endif
6125#ifdef _SC_DCACHE_BLKSZ
6126 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6127#endif
6128#ifdef _SC_DCACHE_LINESZ
6129 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6130#endif
6131#ifdef _SC_DCACHE_SZ
6132 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6133#endif
6134#ifdef _SC_DCACHE_TBLKSZ
6135 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6136#endif
6137#ifdef _SC_DELAYTIMER_MAX
6138 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6139#endif
6140#ifdef _SC_EQUIV_CLASS_MAX
6141 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6142#endif
6143#ifdef _SC_EXPR_NEST_MAX
6144 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6145#endif
6146#ifdef _SC_FSYNC
6147 {"SC_FSYNC", _SC_FSYNC},
6148#endif
6149#ifdef _SC_GETGR_R_SIZE_MAX
6150 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6151#endif
6152#ifdef _SC_GETPW_R_SIZE_MAX
6153 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6154#endif
6155#ifdef _SC_ICACHE_ASSOC
6156 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6157#endif
6158#ifdef _SC_ICACHE_BLKSZ
6159 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6160#endif
6161#ifdef _SC_ICACHE_LINESZ
6162 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6163#endif
6164#ifdef _SC_ICACHE_SZ
6165 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6166#endif
Fred Draked86ed291999-12-15 15:34:33 +00006167#ifdef _SC_INF
6168 {"SC_INF", _SC_INF},
6169#endif
Fred Drakec9680921999-12-13 16:37:25 +00006170#ifdef _SC_INT_MAX
6171 {"SC_INT_MAX", _SC_INT_MAX},
6172#endif
6173#ifdef _SC_INT_MIN
6174 {"SC_INT_MIN", _SC_INT_MIN},
6175#endif
6176#ifdef _SC_IOV_MAX
6177 {"SC_IOV_MAX", _SC_IOV_MAX},
6178#endif
Fred Draked86ed291999-12-15 15:34:33 +00006179#ifdef _SC_IP_SECOPTS
6180 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6181#endif
Fred Drakec9680921999-12-13 16:37:25 +00006182#ifdef _SC_JOB_CONTROL
6183 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6184#endif
Fred Draked86ed291999-12-15 15:34:33 +00006185#ifdef _SC_KERN_POINTERS
6186 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6187#endif
6188#ifdef _SC_KERN_SIM
6189 {"SC_KERN_SIM", _SC_KERN_SIM},
6190#endif
Fred Drakec9680921999-12-13 16:37:25 +00006191#ifdef _SC_LINE_MAX
6192 {"SC_LINE_MAX", _SC_LINE_MAX},
6193#endif
6194#ifdef _SC_LOGIN_NAME_MAX
6195 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6196#endif
6197#ifdef _SC_LOGNAME_MAX
6198 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6199#endif
6200#ifdef _SC_LONG_BIT
6201 {"SC_LONG_BIT", _SC_LONG_BIT},
6202#endif
Fred Draked86ed291999-12-15 15:34:33 +00006203#ifdef _SC_MAC
6204 {"SC_MAC", _SC_MAC},
6205#endif
Fred Drakec9680921999-12-13 16:37:25 +00006206#ifdef _SC_MAPPED_FILES
6207 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6208#endif
6209#ifdef _SC_MAXPID
6210 {"SC_MAXPID", _SC_MAXPID},
6211#endif
6212#ifdef _SC_MB_LEN_MAX
6213 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6214#endif
6215#ifdef _SC_MEMLOCK
6216 {"SC_MEMLOCK", _SC_MEMLOCK},
6217#endif
6218#ifdef _SC_MEMLOCK_RANGE
6219 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6220#endif
6221#ifdef _SC_MEMORY_PROTECTION
6222 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6223#endif
6224#ifdef _SC_MESSAGE_PASSING
6225 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6226#endif
Fred Draked86ed291999-12-15 15:34:33 +00006227#ifdef _SC_MMAP_FIXED_ALIGNMENT
6228 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6229#endif
Fred Drakec9680921999-12-13 16:37:25 +00006230#ifdef _SC_MQ_OPEN_MAX
6231 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6232#endif
6233#ifdef _SC_MQ_PRIO_MAX
6234 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6235#endif
Fred Draked86ed291999-12-15 15:34:33 +00006236#ifdef _SC_NACLS_MAX
6237 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6238#endif
Fred Drakec9680921999-12-13 16:37:25 +00006239#ifdef _SC_NGROUPS_MAX
6240 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6241#endif
6242#ifdef _SC_NL_ARGMAX
6243 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6244#endif
6245#ifdef _SC_NL_LANGMAX
6246 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6247#endif
6248#ifdef _SC_NL_MSGMAX
6249 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6250#endif
6251#ifdef _SC_NL_NMAX
6252 {"SC_NL_NMAX", _SC_NL_NMAX},
6253#endif
6254#ifdef _SC_NL_SETMAX
6255 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6256#endif
6257#ifdef _SC_NL_TEXTMAX
6258 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6259#endif
6260#ifdef _SC_NPROCESSORS_CONF
6261 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6262#endif
6263#ifdef _SC_NPROCESSORS_ONLN
6264 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6265#endif
Fred Draked86ed291999-12-15 15:34:33 +00006266#ifdef _SC_NPROC_CONF
6267 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6268#endif
6269#ifdef _SC_NPROC_ONLN
6270 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6271#endif
Fred Drakec9680921999-12-13 16:37:25 +00006272#ifdef _SC_NZERO
6273 {"SC_NZERO", _SC_NZERO},
6274#endif
6275#ifdef _SC_OPEN_MAX
6276 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6277#endif
6278#ifdef _SC_PAGESIZE
6279 {"SC_PAGESIZE", _SC_PAGESIZE},
6280#endif
6281#ifdef _SC_PAGE_SIZE
6282 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6283#endif
6284#ifdef _SC_PASS_MAX
6285 {"SC_PASS_MAX", _SC_PASS_MAX},
6286#endif
6287#ifdef _SC_PHYS_PAGES
6288 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6289#endif
6290#ifdef _SC_PII
6291 {"SC_PII", _SC_PII},
6292#endif
6293#ifdef _SC_PII_INTERNET
6294 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6295#endif
6296#ifdef _SC_PII_INTERNET_DGRAM
6297 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6298#endif
6299#ifdef _SC_PII_INTERNET_STREAM
6300 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6301#endif
6302#ifdef _SC_PII_OSI
6303 {"SC_PII_OSI", _SC_PII_OSI},
6304#endif
6305#ifdef _SC_PII_OSI_CLTS
6306 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6307#endif
6308#ifdef _SC_PII_OSI_COTS
6309 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6310#endif
6311#ifdef _SC_PII_OSI_M
6312 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6313#endif
6314#ifdef _SC_PII_SOCKET
6315 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6316#endif
6317#ifdef _SC_PII_XTI
6318 {"SC_PII_XTI", _SC_PII_XTI},
6319#endif
6320#ifdef _SC_POLL
6321 {"SC_POLL", _SC_POLL},
6322#endif
6323#ifdef _SC_PRIORITIZED_IO
6324 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6325#endif
6326#ifdef _SC_PRIORITY_SCHEDULING
6327 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6328#endif
6329#ifdef _SC_REALTIME_SIGNALS
6330 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6331#endif
6332#ifdef _SC_RE_DUP_MAX
6333 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6334#endif
6335#ifdef _SC_RTSIG_MAX
6336 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6337#endif
6338#ifdef _SC_SAVED_IDS
6339 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6340#endif
6341#ifdef _SC_SCHAR_MAX
6342 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6343#endif
6344#ifdef _SC_SCHAR_MIN
6345 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6346#endif
6347#ifdef _SC_SELECT
6348 {"SC_SELECT", _SC_SELECT},
6349#endif
6350#ifdef _SC_SEMAPHORES
6351 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6352#endif
6353#ifdef _SC_SEM_NSEMS_MAX
6354 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6355#endif
6356#ifdef _SC_SEM_VALUE_MAX
6357 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6358#endif
6359#ifdef _SC_SHARED_MEMORY_OBJECTS
6360 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6361#endif
6362#ifdef _SC_SHRT_MAX
6363 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6364#endif
6365#ifdef _SC_SHRT_MIN
6366 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6367#endif
6368#ifdef _SC_SIGQUEUE_MAX
6369 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6370#endif
6371#ifdef _SC_SIGRT_MAX
6372 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6373#endif
6374#ifdef _SC_SIGRT_MIN
6375 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6376#endif
Fred Draked86ed291999-12-15 15:34:33 +00006377#ifdef _SC_SOFTPOWER
6378 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6379#endif
Fred Drakec9680921999-12-13 16:37:25 +00006380#ifdef _SC_SPLIT_CACHE
6381 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6382#endif
6383#ifdef _SC_SSIZE_MAX
6384 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6385#endif
6386#ifdef _SC_STACK_PROT
6387 {"SC_STACK_PROT", _SC_STACK_PROT},
6388#endif
6389#ifdef _SC_STREAM_MAX
6390 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6391#endif
6392#ifdef _SC_SYNCHRONIZED_IO
6393 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6394#endif
6395#ifdef _SC_THREADS
6396 {"SC_THREADS", _SC_THREADS},
6397#endif
6398#ifdef _SC_THREAD_ATTR_STACKADDR
6399 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6400#endif
6401#ifdef _SC_THREAD_ATTR_STACKSIZE
6402 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6403#endif
6404#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6405 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6406#endif
6407#ifdef _SC_THREAD_KEYS_MAX
6408 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6409#endif
6410#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6411 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6412#endif
6413#ifdef _SC_THREAD_PRIO_INHERIT
6414 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6415#endif
6416#ifdef _SC_THREAD_PRIO_PROTECT
6417 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6418#endif
6419#ifdef _SC_THREAD_PROCESS_SHARED
6420 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6421#endif
6422#ifdef _SC_THREAD_SAFE_FUNCTIONS
6423 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6424#endif
6425#ifdef _SC_THREAD_STACK_MIN
6426 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6427#endif
6428#ifdef _SC_THREAD_THREADS_MAX
6429 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6430#endif
6431#ifdef _SC_TIMERS
6432 {"SC_TIMERS", _SC_TIMERS},
6433#endif
6434#ifdef _SC_TIMER_MAX
6435 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6436#endif
6437#ifdef _SC_TTY_NAME_MAX
6438 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6439#endif
6440#ifdef _SC_TZNAME_MAX
6441 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6442#endif
6443#ifdef _SC_T_IOV_MAX
6444 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6445#endif
6446#ifdef _SC_UCHAR_MAX
6447 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6448#endif
6449#ifdef _SC_UINT_MAX
6450 {"SC_UINT_MAX", _SC_UINT_MAX},
6451#endif
6452#ifdef _SC_UIO_MAXIOV
6453 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6454#endif
6455#ifdef _SC_ULONG_MAX
6456 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6457#endif
6458#ifdef _SC_USHRT_MAX
6459 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6460#endif
6461#ifdef _SC_VERSION
6462 {"SC_VERSION", _SC_VERSION},
6463#endif
6464#ifdef _SC_WORD_BIT
6465 {"SC_WORD_BIT", _SC_WORD_BIT},
6466#endif
6467#ifdef _SC_XBS5_ILP32_OFF32
6468 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6469#endif
6470#ifdef _SC_XBS5_ILP32_OFFBIG
6471 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6472#endif
6473#ifdef _SC_XBS5_LP64_OFF64
6474 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6475#endif
6476#ifdef _SC_XBS5_LPBIG_OFFBIG
6477 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6478#endif
6479#ifdef _SC_XOPEN_CRYPT
6480 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6481#endif
6482#ifdef _SC_XOPEN_ENH_I18N
6483 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6484#endif
6485#ifdef _SC_XOPEN_LEGACY
6486 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6487#endif
6488#ifdef _SC_XOPEN_REALTIME
6489 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6490#endif
6491#ifdef _SC_XOPEN_REALTIME_THREADS
6492 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6493#endif
6494#ifdef _SC_XOPEN_SHM
6495 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6496#endif
6497#ifdef _SC_XOPEN_UNIX
6498 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6499#endif
6500#ifdef _SC_XOPEN_VERSION
6501 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6502#endif
6503#ifdef _SC_XOPEN_XCU_VERSION
6504 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6505#endif
6506#ifdef _SC_XOPEN_XPG2
6507 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6508#endif
6509#ifdef _SC_XOPEN_XPG3
6510 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6511#endif
6512#ifdef _SC_XOPEN_XPG4
6513 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6514#endif
6515};
6516
6517static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006518conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006519{
6520 return conv_confname(arg, valuep, posix_constants_sysconf,
6521 sizeof(posix_constants_sysconf)
6522 / sizeof(struct constdef));
6523}
6524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006525PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006526"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006527Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006528
6529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006530posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006531{
6532 PyObject *result = NULL;
6533 int name;
6534
6535 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6536 int value;
6537
6538 errno = 0;
6539 value = sysconf(name);
6540 if (value == -1 && errno != 0)
6541 posix_error();
6542 else
Christian Heimes217cfd12007-12-02 14:31:20 +00006543 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00006544 }
6545 return result;
6546}
6547#endif
6548
6549
Fred Drakebec628d1999-12-15 18:31:10 +00006550/* This code is used to ensure that the tables of configuration value names
6551 * are in sorted order as required by conv_confname(), and also to build the
6552 * the exported dictionaries that are used to publish information about the
6553 * names available on the host platform.
6554 *
6555 * Sorting the table at runtime ensures that the table is properly ordered
6556 * when used, even for platforms we're not able to test on. It also makes
6557 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006558 */
Fred Drakebec628d1999-12-15 18:31:10 +00006559
6560static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006561cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006562{
6563 const struct constdef *c1 =
6564 (const struct constdef *) v1;
6565 const struct constdef *c2 =
6566 (const struct constdef *) v2;
6567
6568 return strcmp(c1->name, c2->name);
6569}
6570
6571static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006572setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006573 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006574{
Fred Drakebec628d1999-12-15 18:31:10 +00006575 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006576 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006577
6578 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6579 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006580 if (d == NULL)
6581 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006582
Barry Warsaw3155db32000-04-13 15:20:40 +00006583 for (i=0; i < tablesize; ++i) {
Christian Heimes217cfd12007-12-02 14:31:20 +00006584 PyObject *o = PyLong_FromLong(table[i].value);
Barry Warsaw3155db32000-04-13 15:20:40 +00006585 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6586 Py_XDECREF(o);
6587 Py_DECREF(d);
6588 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006589 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006590 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006591 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006592 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006593}
6594
Fred Drakebec628d1999-12-15 18:31:10 +00006595/* Return -1 on failure, 0 on success. */
6596static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006597setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006598{
6599#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006600 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006601 sizeof(posix_constants_pathconf)
6602 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006603 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006604 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006605#endif
6606#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006607 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006608 sizeof(posix_constants_confstr)
6609 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006610 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006611 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006612#endif
6613#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006614 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006615 sizeof(posix_constants_sysconf)
6616 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006617 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006618 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006619#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006620 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006621}
Fred Draked86ed291999-12-15 15:34:33 +00006622
6623
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006624PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006625"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006626Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006627in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006628
6629static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006630posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006631{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006632 abort();
6633 /*NOTREACHED*/
6634 Py_FatalError("abort() called from Python code didn't abort!");
6635 return NULL;
6636}
Fred Drakebec628d1999-12-15 18:31:10 +00006637
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006638#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006639PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00006640"startfile(filepath [, operation]) - Start a file with its associated\n\
6641application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006642\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00006643When \"operation\" is not specified or \"open\", this acts like\n\
6644double-clicking the file in Explorer, or giving the file name as an\n\
6645argument to the DOS \"start\" command: the file is opened with whatever\n\
6646application (if any) its extension is associated.\n\
6647When another \"operation\" is given, it specifies what should be done with\n\
6648the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006649\n\
6650startfile returns as soon as the associated application is launched.\n\
6651There is no option to wait for the application to close, and no way\n\
6652to retrieve the application's exit status.\n\
6653\n\
6654The filepath is relative to the current directory. If you want to use\n\
6655an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006656the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006657
6658static PyObject *
6659win32_startfile(PyObject *self, PyObject *args)
6660{
6661 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00006662 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00006663 HINSTANCE rc;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006664#ifdef Py_WIN_WIDE_FILENAMES
6665 if (unicode_file_names()) {
6666 PyObject *unipath, *woperation = NULL;
6667 if (!PyArg_ParseTuple(args, "U|s:startfile",
6668 &unipath, &operation)) {
6669 PyErr_Clear();
6670 goto normal;
6671 }
6672
6673
6674 if (operation) {
6675 woperation = PyUnicode_DecodeASCII(operation,
6676 strlen(operation), NULL);
6677 if (!woperation) {
6678 PyErr_Clear();
6679 operation = NULL;
6680 goto normal;
6681 }
6682 }
6683
6684 Py_BEGIN_ALLOW_THREADS
6685 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6686 PyUnicode_AS_UNICODE(unipath),
6687 NULL, NULL, SW_SHOWNORMAL);
6688 Py_END_ALLOW_THREADS
6689
6690 Py_XDECREF(woperation);
6691 if (rc <= (HINSTANCE)32) {
6692 PyObject *errval = win32_error_unicode("startfile",
6693 PyUnicode_AS_UNICODE(unipath));
6694 return errval;
6695 }
6696 Py_INCREF(Py_None);
6697 return Py_None;
6698 }
6699#endif
6700
6701normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00006702 if (!PyArg_ParseTuple(args, "et|s:startfile",
6703 Py_FileSystemDefaultEncoding, &filepath,
6704 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00006705 return NULL;
6706 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00006707 rc = ShellExecute((HWND)0, operation, filepath,
6708 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006709 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00006710 if (rc <= (HINSTANCE)32) {
6711 PyObject *errval = win32_error("startfile", filepath);
6712 PyMem_Free(filepath);
6713 return errval;
6714 }
6715 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00006716 Py_INCREF(Py_None);
6717 return Py_None;
6718}
6719#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006720
Martin v. Löwis438b5342002-12-27 10:16:42 +00006721#ifdef HAVE_GETLOADAVG
6722PyDoc_STRVAR(posix_getloadavg__doc__,
6723"getloadavg() -> (float, float, float)\n\n\
6724Return the number of processes in the system run queue averaged over\n\
6725the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6726was unobtainable");
6727
6728static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006729posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006730{
6731 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006732 if (getloadavg(loadavg, 3)!=3) {
6733 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6734 return NULL;
6735 } else
6736 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6737}
6738#endif
6739
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006740#ifdef MS_WINDOWS
6741
6742PyDoc_STRVAR(win32_urandom__doc__,
6743"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006744Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006745
6746typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6747 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6748 DWORD dwFlags );
6749typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6750 BYTE *pbBuffer );
6751
6752static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00006753/* This handle is never explicitly released. Instead, the operating
6754 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006755static HCRYPTPROV hCryptProv = 0;
6756
Tim Peters4ad82172004-08-30 17:02:04 +00006757static PyObject*
6758win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006759{
Tim Petersd3115382004-08-30 17:36:46 +00006760 int howMany;
6761 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006762
Tim Peters4ad82172004-08-30 17:02:04 +00006763 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00006764 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00006765 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00006766 if (howMany < 0)
6767 return PyErr_Format(PyExc_ValueError,
6768 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006769
Tim Peters4ad82172004-08-30 17:02:04 +00006770 if (hCryptProv == 0) {
6771 HINSTANCE hAdvAPI32 = NULL;
6772 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006773
Tim Peters4ad82172004-08-30 17:02:04 +00006774 /* Obtain handle to the DLL containing CryptoAPI
6775 This should not fail */
6776 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6777 if(hAdvAPI32 == NULL)
6778 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006779
Tim Peters4ad82172004-08-30 17:02:04 +00006780 /* Obtain pointers to the CryptoAPI functions
6781 This will fail on some early versions of Win95 */
6782 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6783 hAdvAPI32,
6784 "CryptAcquireContextA");
6785 if (pCryptAcquireContext == NULL)
6786 return PyErr_Format(PyExc_NotImplementedError,
6787 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006788
Tim Peters4ad82172004-08-30 17:02:04 +00006789 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6790 hAdvAPI32, "CryptGenRandom");
Thomas Wouters89f507f2006-12-13 04:49:30 +00006791 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00006792 return PyErr_Format(PyExc_NotImplementedError,
6793 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006794
Tim Peters4ad82172004-08-30 17:02:04 +00006795 /* Acquire context */
6796 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
6797 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
6798 return win32_error("CryptAcquireContext", NULL);
6799 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006800
Tim Peters4ad82172004-08-30 17:02:04 +00006801 /* Allocate bytes */
Christian Heimes72b710a2008-05-26 13:28:38 +00006802 result = PyBytes_FromStringAndSize(NULL, howMany);
Tim Petersd3115382004-08-30 17:36:46 +00006803 if (result != NULL) {
6804 /* Get random data */
Amaury Forgeot d'Arca05ada32008-07-21 21:13:14 +00006805 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
Tim Petersd3115382004-08-30 17:36:46 +00006806 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
Christian Heimes72b710a2008-05-26 13:28:38 +00006807 PyBytes_AS_STRING(result))) {
Tim Petersd3115382004-08-30 17:36:46 +00006808 Py_DECREF(result);
6809 return win32_error("CryptGenRandom", NULL);
6810 }
Tim Peters4ad82172004-08-30 17:02:04 +00006811 }
Tim Petersd3115382004-08-30 17:36:46 +00006812 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00006813}
6814#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00006815
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006816PyDoc_STRVAR(device_encoding__doc__,
6817"device_encoding(fd) -> str\n\n\
6818Return a string describing the encoding of the device\n\
6819if the output is a terminal; else return None.");
6820
6821static PyObject *
6822device_encoding(PyObject *self, PyObject *args)
6823{
6824 int fd;
6825 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
6826 return NULL;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00006827 if (!_PyVerify_fd(fd))
6828 return posix_error();
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006829 if (!isatty(fd)) {
6830 Py_INCREF(Py_None);
6831 return Py_None;
6832 }
6833#if defined(MS_WINDOWS) || defined(MS_WIN64)
6834 if (fd == 0) {
6835 char buf[100];
6836 sprintf(buf, "cp%d", GetConsoleCP());
6837 return PyUnicode_FromString(buf);
6838 }
6839 if (fd == 1 || fd == 2) {
6840 char buf[100];
6841 sprintf(buf, "cp%d", GetConsoleOutputCP());
6842 return PyUnicode_FromString(buf);
6843 }
6844#elif defined(CODESET)
6845 {
6846 char *codeset = nl_langinfo(CODESET);
Mark Dickinsonda2706b2008-12-11 18:03:03 +00006847 if (codeset != NULL && codeset[0] != 0)
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00006848 return PyUnicode_FromString(codeset);
6849 }
6850#endif
6851 Py_INCREF(Py_None);
6852 return Py_None;
6853}
6854
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006855#ifdef __VMS
6856/* Use openssl random routine */
6857#include <openssl/rand.h>
6858PyDoc_STRVAR(vms_urandom__doc__,
6859"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00006860Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006861
6862static PyObject*
6863vms_urandom(PyObject *self, PyObject *args)
6864{
6865 int howMany;
6866 PyObject* result;
6867
6868 /* Read arguments */
6869 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
6870 return NULL;
6871 if (howMany < 0)
6872 return PyErr_Format(PyExc_ValueError,
6873 "negative argument not allowed");
6874
6875 /* Allocate bytes */
Christian Heimes72b710a2008-05-26 13:28:38 +00006876 result = PyBytes_FromStringAndSize(NULL, howMany);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006877 if (result != NULL) {
6878 /* Get random data */
6879 if (RAND_pseudo_bytes((unsigned char*)
Christian Heimes72b710a2008-05-26 13:28:38 +00006880 PyBytes_AS_STRING(result),
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006881 howMany) < 0) {
6882 Py_DECREF(result);
6883 return PyErr_Format(PyExc_ValueError,
6884 "RAND_pseudo_bytes");
6885 }
6886 }
6887 return result;
6888}
6889#endif
6890
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006891static PyMethodDef posix_methods[] = {
6892 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6893#ifdef HAVE_TTYNAME
6894 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6895#endif
6896 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00006897#ifdef HAVE_CHFLAGS
6898 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
6899#endif /* HAVE_CHFLAGS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006900 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00006901#ifdef HAVE_FCHMOD
6902 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
6903#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006904#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006905 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006906#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00006907#ifdef HAVE_LCHMOD
6908 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
6909#endif /* HAVE_LCHMOD */
6910#ifdef HAVE_FCHOWN
6911 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
6912#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00006913#ifdef HAVE_LCHFLAGS
6914 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
6915#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006916#ifdef HAVE_LCHOWN
6917 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6918#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006919#ifdef HAVE_CHROOT
6920 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6921#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006922#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006923 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006924#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006925#ifdef HAVE_GETCWD
Guido van Rossumf0af3e32008-10-02 18:55:37 +00006926 {"getcwd", (PyCFunction)posix_getcwd_unicode,
6927 METH_NOARGS, posix_getcwd__doc__},
6928 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
6929 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006930#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006931#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006932 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006933#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006934 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6935 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6936 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006937#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006938 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006939#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006940#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006941 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006942#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006943 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6944 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6945 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006946 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006947#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006948 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006949#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006950#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006951 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006952#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006953 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006954#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00006955 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006956#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006957 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6958 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6959 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006960#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00006961 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006962#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006963 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006964#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006965 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6966 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006967#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006968#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006969 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6970 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00006971#if defined(PYOS_OS2)
6972 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
6973 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
6974#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00006975#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006976#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00006977 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006978#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006979#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00006980 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006981#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006982#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00006983 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006984#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006985#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00006986 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00006987#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006988#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006989 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006990#endif /* HAVE_GETEGID */
6991#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006992 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006993#endif /* HAVE_GETEUID */
6994#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006995 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006996#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006997#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00006998 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00006999#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007000 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007001#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007002 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007003#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007004#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007005 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007006#endif /* HAVE_GETPPID */
7007#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007008 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007009#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007010#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007011 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007012#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007013#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007014 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007015#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007016#ifdef HAVE_KILLPG
7017 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7018#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007019#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007020 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007021#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007022#ifdef MS_WINDOWS
7023 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7024#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007025#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007026 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007027#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007028#ifdef HAVE_SETEUID
7029 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7030#endif /* HAVE_SETEUID */
7031#ifdef HAVE_SETEGID
7032 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7033#endif /* HAVE_SETEGID */
7034#ifdef HAVE_SETREUID
7035 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7036#endif /* HAVE_SETREUID */
7037#ifdef HAVE_SETREGID
7038 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7039#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007040#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007041 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007042#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007043#ifdef HAVE_SETGROUPS
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00007044 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007045#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007046#ifdef HAVE_GETPGID
7047 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7048#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007049#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007050 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007051#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007052#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007053 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007054#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007055#ifdef HAVE_WAIT3
7056 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
7057#endif /* HAVE_WAIT3 */
7058#ifdef HAVE_WAIT4
7059 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
7060#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007061#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007062 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007063#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007064#ifdef HAVE_GETSID
7065 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7066#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007067#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007068 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007069#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007070#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007071 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007072#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007073#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007074 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007075#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007076#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007077 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007078#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007079 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7080 {"close", posix_close, METH_VARARGS, posix_close__doc__},
Christian Heimesfdab48e2008-01-20 09:06:41 +00007081 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007082 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007083 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7084 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7085 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7086 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7087 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7088 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007089 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007090#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007091 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007092#endif
7093#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007094 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007095#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007096#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007097 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7098#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007099#ifdef HAVE_DEVICE_MACROS
7100 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7101 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7102 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7103#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007104#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007105 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007106#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007107#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007108 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007109#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007110#ifdef HAVE_UNSETENV
7111 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7112#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007113 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007114#ifdef HAVE_FCHDIR
7115 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7116#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007117#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007118 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007119#endif
7120#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007121 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007122#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007123#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007124#ifdef WCOREDUMP
7125 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7126#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007127#ifdef WIFCONTINUED
7128 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7129#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007130#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007131 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007132#endif /* WIFSTOPPED */
7133#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007134 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007135#endif /* WIFSIGNALED */
7136#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007137 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007138#endif /* WIFEXITED */
7139#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007140 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007141#endif /* WEXITSTATUS */
7142#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007143 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007144#endif /* WTERMSIG */
7145#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007146 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007147#endif /* WSTOPSIG */
7148#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007149#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007150 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007151#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007152#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007153 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007154#endif
Fred Drakec9680921999-12-13 16:37:25 +00007155#ifdef HAVE_CONFSTR
7156 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7157#endif
7158#ifdef HAVE_SYSCONF
7159 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7160#endif
7161#ifdef HAVE_FPATHCONF
7162 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7163#endif
7164#ifdef HAVE_PATHCONF
7165 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7166#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007167 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007168#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007169 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7170#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007171#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007172 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007173#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007174 #ifdef MS_WINDOWS
7175 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7176 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007177 #ifdef __VMS
7178 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
7179 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007180 {NULL, NULL} /* Sentinel */
7181};
7182
7183
Barry Warsaw4a342091996-12-19 23:50:02 +00007184static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007185ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007186{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007187 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007188}
7189
Guido van Rossumd48f2521997-12-05 22:19:34 +00007190#if defined(PYOS_OS2)
7191/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007192static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007193{
7194 APIRET rc;
7195 ULONG values[QSV_MAX+1];
7196 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007197 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007198
7199 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007200 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007201 Py_END_ALLOW_THREADS
7202
7203 if (rc != NO_ERROR) {
7204 os2_error(rc);
7205 return -1;
7206 }
7207
Fred Drake4d1e64b2002-04-15 19:40:07 +00007208 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7209 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7210 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7211 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7212 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7213 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7214 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007215
7216 switch (values[QSV_VERSION_MINOR]) {
7217 case 0: ver = "2.00"; break;
7218 case 10: ver = "2.10"; break;
7219 case 11: ver = "2.11"; break;
7220 case 30: ver = "3.00"; break;
7221 case 40: ver = "4.00"; break;
7222 case 50: ver = "5.00"; break;
7223 default:
Tim Peters885d4572001-11-28 20:27:42 +00007224 PyOS_snprintf(tmp, sizeof(tmp),
7225 "%d-%d", values[QSV_VERSION_MAJOR],
7226 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007227 ver = &tmp[0];
7228 }
7229
7230 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007231 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007232 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007233
7234 /* Add Indicator of Which Drive was Used to Boot the System */
7235 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7236 tmp[1] = ':';
7237 tmp[2] = '\0';
7238
Fred Drake4d1e64b2002-04-15 19:40:07 +00007239 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007240}
7241#endif
7242
Barry Warsaw4a342091996-12-19 23:50:02 +00007243static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007244all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007245{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007246#ifdef F_OK
7247 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007248#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007249#ifdef R_OK
7250 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007251#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007252#ifdef W_OK
7253 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007254#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007255#ifdef X_OK
7256 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007257#endif
Fred Drakec9680921999-12-13 16:37:25 +00007258#ifdef NGROUPS_MAX
7259 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7260#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007261#ifdef TMP_MAX
7262 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7263#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007264#ifdef WCONTINUED
7265 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7266#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007267#ifdef WNOHANG
7268 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007269#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007270#ifdef WUNTRACED
7271 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7272#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007273#ifdef O_RDONLY
7274 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7275#endif
7276#ifdef O_WRONLY
7277 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7278#endif
7279#ifdef O_RDWR
7280 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7281#endif
7282#ifdef O_NDELAY
7283 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7284#endif
7285#ifdef O_NONBLOCK
7286 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7287#endif
7288#ifdef O_APPEND
7289 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7290#endif
7291#ifdef O_DSYNC
7292 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7293#endif
7294#ifdef O_RSYNC
7295 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7296#endif
7297#ifdef O_SYNC
7298 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7299#endif
7300#ifdef O_NOCTTY
7301 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7302#endif
7303#ifdef O_CREAT
7304 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7305#endif
7306#ifdef O_EXCL
7307 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7308#endif
7309#ifdef O_TRUNC
7310 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7311#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007312#ifdef O_BINARY
7313 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7314#endif
7315#ifdef O_TEXT
7316 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7317#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007318#ifdef O_LARGEFILE
7319 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7320#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007321#ifdef O_SHLOCK
7322 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7323#endif
7324#ifdef O_EXLOCK
7325 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7326#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007327
Tim Peters5aa91602002-01-30 05:46:57 +00007328/* MS Windows */
7329#ifdef O_NOINHERIT
7330 /* Don't inherit in child processes. */
7331 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7332#endif
7333#ifdef _O_SHORT_LIVED
7334 /* Optimize for short life (keep in memory). */
7335 /* MS forgot to define this one with a non-underscore form too. */
7336 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7337#endif
7338#ifdef O_TEMPORARY
7339 /* Automatically delete when last handle is closed. */
7340 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7341#endif
7342#ifdef O_RANDOM
7343 /* Optimize for random access. */
7344 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7345#endif
7346#ifdef O_SEQUENTIAL
7347 /* Optimize for sequential access. */
7348 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7349#endif
7350
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007351/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00007352#ifdef O_ASYNC
7353 /* Send a SIGIO signal whenever input or output
7354 becomes available on file descriptor */
7355 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
7356#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007357#ifdef O_DIRECT
7358 /* Direct disk access. */
7359 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7360#endif
7361#ifdef O_DIRECTORY
7362 /* Must be a directory. */
7363 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7364#endif
7365#ifdef O_NOFOLLOW
7366 /* Do not follow links. */
7367 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7368#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00007369#ifdef O_NOATIME
7370 /* Do not update the access time. */
7371 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
7372#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007373
Barry Warsaw5676bd12003-01-07 20:57:09 +00007374 /* These come from sysexits.h */
7375#ifdef EX_OK
7376 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007377#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007378#ifdef EX_USAGE
7379 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007380#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007381#ifdef EX_DATAERR
7382 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007383#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007384#ifdef EX_NOINPUT
7385 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007386#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007387#ifdef EX_NOUSER
7388 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007389#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007390#ifdef EX_NOHOST
7391 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007392#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007393#ifdef EX_UNAVAILABLE
7394 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007395#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007396#ifdef EX_SOFTWARE
7397 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007398#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007399#ifdef EX_OSERR
7400 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007401#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007402#ifdef EX_OSFILE
7403 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007404#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007405#ifdef EX_CANTCREAT
7406 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007407#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007408#ifdef EX_IOERR
7409 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007410#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007411#ifdef EX_TEMPFAIL
7412 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007413#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007414#ifdef EX_PROTOCOL
7415 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007416#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007417#ifdef EX_NOPERM
7418 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007419#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007420#ifdef EX_CONFIG
7421 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007422#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007423#ifdef EX_NOTFOUND
7424 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007425#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007426
Guido van Rossum246bc171999-02-01 23:54:31 +00007427#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007428#if defined(PYOS_OS2) && defined(PYCC_GCC)
7429 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7430 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7431 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7432 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7433 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7434 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7435 if (ins(d, "P_PM", (long)P_PM)) return -1;
7436 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7437 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7438 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7439 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7440 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7441 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7442 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7443 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7444 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7445 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7446 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7447 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7448 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7449#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007450 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7451 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7452 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7453 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7454 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007455#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007456#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007457
Guido van Rossumd48f2521997-12-05 22:19:34 +00007458#if defined(PYOS_OS2)
7459 if (insertvalues(d)) return -1;
7460#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007461 return 0;
7462}
7463
7464
Tim Peters5aa91602002-01-30 05:46:57 +00007465#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007466#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007467#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007468
7469#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007470#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007471#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007472
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007473#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00007474#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007475#define MODNAME "posix"
7476#endif
7477
Martin v. Löwis1a214512008-06-11 05:26:20 +00007478static struct PyModuleDef posixmodule = {
7479 PyModuleDef_HEAD_INIT,
7480 MODNAME,
7481 posix__doc__,
7482 -1,
7483 posix_methods,
7484 NULL,
7485 NULL,
7486 NULL,
7487 NULL
7488};
7489
7490
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007491PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007492INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007493{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007494 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007495
Martin v. Löwis1a214512008-06-11 05:26:20 +00007496 m = PyModule_Create(&posixmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00007497 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007498 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007499
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007500 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007501 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007502 Py_XINCREF(v);
7503 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00007504 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00007505 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007506
Fred Drake4d1e64b2002-04-15 19:40:07 +00007507 if (all_ins(m))
Martin v. Löwis1a214512008-06-11 05:26:20 +00007508 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00007509
Fred Drake4d1e64b2002-04-15 19:40:07 +00007510 if (setup_confname_tables(m))
Martin v. Löwis1a214512008-06-11 05:26:20 +00007511 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00007512
Fred Drake4d1e64b2002-04-15 19:40:07 +00007513 Py_INCREF(PyExc_OSError);
7514 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007515
Guido van Rossumb3d39562000-01-31 18:41:26 +00007516#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007517 if (posix_putenv_garbage == NULL)
7518 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007519#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007520
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007521 if (!initialized) {
7522 stat_result_desc.name = MODNAME ".stat_result";
7523 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7524 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7525 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7526 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7527 structseq_new = StatResultType.tp_new;
7528 StatResultType.tp_new = statresult_new;
7529
7530 statvfs_result_desc.name = MODNAME ".statvfs_result";
7531 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00007532#ifdef NEED_TICKS_PER_SECOND
7533# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
7534 ticks_per_second = sysconf(_SC_CLK_TCK);
7535# elif defined(HZ)
7536 ticks_per_second = HZ;
7537# else
7538 ticks_per_second = 60; /* magic fallback value; may be bogus */
7539# endif
7540#endif
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007541 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007542 Py_INCREF((PyObject*) &StatResultType);
7543 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007544 Py_INCREF((PyObject*) &StatVFSResultType);
7545 PyModule_AddObject(m, "statvfs_result",
7546 (PyObject*) &StatVFSResultType);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007547 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007548
7549#ifdef __APPLE__
7550 /*
7551 * Step 2 of weak-linking support on Mac OS X.
7552 *
7553 * The code below removes functions that are not available on the
7554 * currently active platform.
7555 *
7556 * This block allow one to use a python binary that was build on
7557 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7558 * OSX 10.4.
7559 */
7560#ifdef HAVE_FSTATVFS
7561 if (fstatvfs == NULL) {
7562 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007563 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007564 }
7565 }
7566#endif /* HAVE_FSTATVFS */
7567
7568#ifdef HAVE_STATVFS
7569 if (statvfs == NULL) {
7570 if (PyObject_DelAttrString(m, "statvfs") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007571 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007572 }
7573 }
7574#endif /* HAVE_STATVFS */
7575
7576# ifdef HAVE_LCHOWN
7577 if (lchown == NULL) {
7578 if (PyObject_DelAttrString(m, "lchown") == -1) {
Martin v. Löwis1a214512008-06-11 05:26:20 +00007579 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007580 }
7581 }
7582#endif /* HAVE_LCHOWN */
7583
7584
7585#endif /* __APPLE__ */
Martin v. Löwis1a214512008-06-11 05:26:20 +00007586 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00007587
Guido van Rossumb6775db1994-08-01 11:34:53 +00007588}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007589
7590#ifdef __cplusplus
7591}
7592#endif