blob: a3e106a0c95fa4c2955a8396c1cb61e52103232e [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 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000018 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000019 * 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
Victor Stinner8c62be82010-05-06 00:08:46 +000072#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000073#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
Victor Stinner8c62be82010-05-06 00:08:46 +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
Victor Stinner8c62be82010-05-06 00:08:46 +0000107#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#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
Victor Stinner8c62be82010-05-06 00:08:46 +0000114#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000115#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
Victor Stinner8c62be82010-05-06 00:08:46 +0000119#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#define HAVE_WAIT 1
121#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000122#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000123#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000124#define HAVE_GETPPID 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000125#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000126#define HAVE_EXECV 1
127#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000128#define HAVE_SYSTEM 1
129#define HAVE_CWAIT 1
130#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000131#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000132#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000133#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
134/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000135#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136/* Unix functions that the configure script doesn't check for */
137#define HAVE_EXECV 1
138#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000139#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000140#define HAVE_FORK1 1
141#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142#define HAVE_GETCWD 1
143#define HAVE_GETEGID 1
144#define HAVE_GETEUID 1
145#define HAVE_GETGID 1
146#define HAVE_GETPPID 1
147#define HAVE_GETUID 1
148#define HAVE_KILL 1
149#define HAVE_OPENDIR 1
150#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000152#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000153#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000154#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#endif /* _MSC_VER */
156#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000157#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000158#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000159
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000161
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000162#if defined(__sgi)&&_COMPILER_VERSION>=700
163/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
164 (default) */
165extern char *ctermid_r(char *);
166#endif
167
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000168#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000169#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000170extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000171#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000172#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000173extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000174#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000175extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000177#endif
178#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000179extern int chdir(char *);
180extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000181#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000182extern int chdir(const char *);
183extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000184#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000185#ifdef __BORLANDC__
186extern int chmod(const char *, int);
187#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000188extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000189#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000190/*#ifdef HAVE_FCHMOD
191extern int fchmod(int, mode_t);
192#endif*/
193/*#ifdef HAVE_LCHMOD
194extern int lchmod(const char *, mode_t);
195#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000196extern int chown(const char *, uid_t, gid_t);
197extern char *getcwd(char *, int);
198extern char *strerror(int);
199extern int link(const char *, const char *);
200extern int rename(const char *, const char *);
201extern int stat(const char *, struct stat *);
202extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000203#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000205#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000206#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000207extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000208#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000210
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000211#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212
Guido van Rossumb6775db1994-08-01 11:34:53 +0000213#ifdef HAVE_UTIME_H
214#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000215#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000217#ifdef HAVE_SYS_UTIME_H
218#include <sys/utime.h>
219#define HAVE_UTIME_H /* pretend we do for the rest of this file */
220#endif /* HAVE_SYS_UTIME_H */
221
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#ifdef HAVE_SYS_TIMES_H
223#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000224#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225
226#ifdef HAVE_SYS_PARAM_H
227#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000228#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229
230#ifdef HAVE_SYS_UTSNAME_H
231#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000232#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000234#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000236#define NAMLEN(dirent) strlen((dirent)->d_name)
237#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000238#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000239#include <direct.h>
240#define NAMLEN(dirent) strlen((dirent)->d_name)
241#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000243#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000244#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000245#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000247#endif
248#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000250#endif
251#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000253#endif
254#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000256#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000257#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000259#endif
260#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000262#endif
263#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000265#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000266#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000267#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000268#endif
269#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000270#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000271#endif
272#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000273#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000274#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000275#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000276#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000278#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000279#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280
Guido van Rossumd48f2521997-12-05 22:19:34 +0000281#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000283#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284
Tim Petersbc2e10e2002-03-03 23:17:02 +0000285#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000286#if defined(PATH_MAX) && PATH_MAX > 1024
287#define MAXPATHLEN PATH_MAX
288#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000289#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000290#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000291#endif /* MAXPATHLEN */
292
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000293#ifdef UNION_WAIT
294/* Emulate some macros on systems that have a union instead of macros */
295
296#ifndef WIFEXITED
297#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
298#endif
299
300#ifndef WEXITSTATUS
301#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
302#endif
303
304#ifndef WTERMSIG
305#define WTERMSIG(u_wait) ((u_wait).w_termsig)
306#endif
307
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000308#define WAIT_TYPE union wait
309#define WAIT_STATUS_INT(s) (s.w_status)
310
311#else /* !UNION_WAIT */
312#define WAIT_TYPE int
313#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000314#endif /* UNION_WAIT */
315
Greg Wardb48bc172000-03-01 21:51:56 +0000316/* Don't use the "_r" form if we don't need it (also, won't have a
317 prototype for it, at least on Solaris -- maybe others as well?). */
318#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
319#define USE_CTERMID_R
320#endif
321
Fred Drake699f3522000-06-29 21:12:41 +0000322/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000323#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000324#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000325# define STAT win32_stat
326# define FSTAT win32_fstat
327# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000328#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000329# define STAT stat
330# define FSTAT fstat
331# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000332#endif
333
Tim Peters11b23062003-04-23 02:39:17 +0000334#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000335#include <sys/mkdev.h>
336#else
337#if defined(MAJOR_IN_SYSMACROS)
338#include <sys/sysmacros.h>
339#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000340#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
341#include <sys/mkdev.h>
342#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000343#endif
Fred Drake699f3522000-06-29 21:12:41 +0000344
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000345#if defined _MSC_VER && _MSC_VER >= 1400
346/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
347 * valid and throw an assertion if it isn't.
348 * Normally, an invalid fd is likely to be a C program error and therefore
349 * an assertion can be useful, but it does contradict the POSIX standard
350 * which for write(2) states:
351 * "Otherwise, -1 shall be returned and errno set to indicate the error."
352 * "[EBADF] The fildes argument is not a valid file descriptor open for
353 * writing."
354 * Furthermore, python allows the user to enter any old integer
355 * as a fd and should merely raise a python exception on error.
356 * The Microsoft CRT doesn't provide an official way to check for the
357 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000358 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000359 * internal structures involved.
360 * The structures below must be updated for each version of visual studio
361 * according to the file internal.h in the CRT source, until MS comes
362 * up with a less hacky way to do this.
363 * (all of this is to avoid globally modifying the CRT behaviour using
364 * _set_invalid_parameter_handler() and _CrtSetReportMode())
365 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000366/* The actual size of the structure is determined at runtime.
367 * Only the first items must be present.
368 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000369typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000370 intptr_t osfhnd;
371 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000372} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000373
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000374extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000375#define IOINFO_L2E 5
376#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
377#define IOINFO_ARRAYS 64
378#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
379#define FOPEN 0x01
380#define _NO_CONSOLE_FILENO (intptr_t)-2
381
382/* This function emulates what the windows CRT does to validate file handles */
383int
384_PyVerify_fd(int fd)
385{
Victor Stinner8c62be82010-05-06 00:08:46 +0000386 const int i1 = fd >> IOINFO_L2E;
387 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000388
Antoine Pitrou22e41552010-08-15 18:07:50 +0000389 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000390
Victor Stinner8c62be82010-05-06 00:08:46 +0000391 /* Determine the actual size of the ioinfo structure,
392 * as used by the CRT loaded in memory
393 */
394 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
395 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
396 }
397 if (sizeof_ioinfo == 0) {
398 /* This should not happen... */
399 goto fail;
400 }
401
402 /* See that it isn't a special CLEAR fileno */
403 if (fd != _NO_CONSOLE_FILENO) {
404 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
405 * we check pointer validity and other info
406 */
407 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
408 /* finally, check that the file is open */
409 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
410 if (info->osfile & FOPEN) {
411 return 1;
412 }
413 }
414 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000415 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000416 errno = EBADF;
417 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000418}
419
420/* the special case of checking dup2. The target fd must be in a sensible range */
421static int
422_PyVerify_fd_dup2(int fd1, int fd2)
423{
Victor Stinner8c62be82010-05-06 00:08:46 +0000424 if (!_PyVerify_fd(fd1))
425 return 0;
426 if (fd2 == _NO_CONSOLE_FILENO)
427 return 0;
428 if ((unsigned)fd2 < _NHANDLE_)
429 return 1;
430 else
431 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000432}
433#else
434/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
435#define _PyVerify_fd_dup2(A, B) (1)
436#endif
437
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000438/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000439#ifdef WITH_NEXT_FRAMEWORK
440/* On Darwin/MacOSX a shared library or framework has no access to
441** environ directly, we must obtain it with _NSGetEnviron().
442*/
443#include <crt_externs.h>
444static char **environ;
445#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000446extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000447#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000448
Barry Warsaw53699e91996-12-10 23:23:01 +0000449static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000450convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000451{
Victor Stinner8c62be82010-05-06 00:08:46 +0000452 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000453#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000454 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000455#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000456 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000457#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000458#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000459 APIRET rc;
460 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
461#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000462
Victor Stinner8c62be82010-05-06 00:08:46 +0000463 d = PyDict_New();
464 if (d == NULL)
465 return NULL;
466#ifdef WITH_NEXT_FRAMEWORK
467 if (environ == NULL)
468 environ = *_NSGetEnviron();
469#endif
470#ifdef MS_WINDOWS
471 /* _wenviron must be initialized in this way if the program is started
472 through main() instead of wmain(). */
473 _wgetenv(L"");
474 if (_wenviron == NULL)
475 return d;
476 /* This part ignores errors */
477 for (e = _wenviron; *e != NULL; e++) {
478 PyObject *k;
479 PyObject *v;
480 wchar_t *p = wcschr(*e, L'=');
481 if (p == NULL)
482 continue;
483 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
484 if (k == NULL) {
485 PyErr_Clear();
486 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000487 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000488 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
489 if (v == NULL) {
490 PyErr_Clear();
491 Py_DECREF(k);
492 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000493 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000494 if (PyDict_GetItem(d, k) == NULL) {
495 if (PyDict_SetItem(d, k, v) != 0)
496 PyErr_Clear();
497 }
498 Py_DECREF(k);
499 Py_DECREF(v);
500 }
501#else
502 if (environ == NULL)
503 return d;
504 /* This part ignores errors */
505 for (e = environ; *e != NULL; e++) {
506 PyObject *k;
507 PyObject *v;
508 char *p = strchr(*e, '=');
509 if (p == NULL)
510 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000511 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000512 if (k == NULL) {
513 PyErr_Clear();
514 continue;
515 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000516 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000517 if (v == NULL) {
518 PyErr_Clear();
519 Py_DECREF(k);
520 continue;
521 }
522 if (PyDict_GetItem(d, k) == NULL) {
523 if (PyDict_SetItem(d, k, v) != 0)
524 PyErr_Clear();
525 }
526 Py_DECREF(k);
527 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000528 }
529#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000530#if defined(PYOS_OS2)
531 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
532 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
533 PyObject *v = PyBytes_FromString(buffer);
534 PyDict_SetItemString(d, "BEGINLIBPATH", v);
535 Py_DECREF(v);
536 }
537 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
538 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
539 PyObject *v = PyBytes_FromString(buffer);
540 PyDict_SetItemString(d, "ENDLIBPATH", v);
541 Py_DECREF(v);
542 }
543#endif
544 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000545}
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{
Victor Stinner8c62be82010-05-06 00:08:46 +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{
Victor Stinner8c62be82010-05-06 00:08:46 +0000557 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000558}
559
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000560
Mark Hammondef8b6542001-05-13 08:04:26 +0000561static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000562posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000563{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000564 PyObject *name_str, *rc;
565 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
566 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000567 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000568 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
569 name_str);
570 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000571 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000572}
573
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000574#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000575static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000576win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000577{
Victor Stinner8c62be82010-05-06 00:08:46 +0000578 /* XXX We should pass the function name along in the future.
579 (winreg.c also wants to pass the function name.)
580 This would however require an additional param to the
581 Windows error object, which is non-trivial.
582 */
583 errno = GetLastError();
584 if (filename)
585 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
586 else
587 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000588}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000589
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000590static PyObject *
591win32_error_unicode(char* function, Py_UNICODE* filename)
592{
Victor Stinner8c62be82010-05-06 00:08:46 +0000593 /* XXX - see win32_error for comments on 'function' */
594 errno = GetLastError();
595 if (filename)
596 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
597 else
598 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000599}
600
Thomas Wouters477c8d52006-05-27 19:21:47 +0000601static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000602convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000603{
Victor Stinner8c62be82010-05-06 00:08:46 +0000604 if (PyUnicode_CheckExact(*param))
605 Py_INCREF(*param);
606 else if (PyUnicode_Check(*param))
607 /* For a Unicode subtype that's not a Unicode object,
608 return a true Unicode object with the same data. */
609 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
610 PyUnicode_GET_SIZE(*param));
611 else
612 *param = PyUnicode_FromEncodedObject(*param,
613 Py_FileSystemDefaultEncoding,
614 "strict");
615 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000616}
617
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000618#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000619
Guido van Rossumd48f2521997-12-05 22:19:34 +0000620#if defined(PYOS_OS2)
621/**********************************************************************
622 * Helper Function to Trim and Format OS/2 Messages
623 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000624static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000625os2_formatmsg(char *msgbuf, int msglen, char *reason)
626{
627 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
628
629 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
630 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
631
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000632 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000633 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
634 }
635
636 /* Add Optional Reason Text */
637 if (reason) {
638 strcat(msgbuf, " : ");
639 strcat(msgbuf, reason);
640 }
641}
642
643/**********************************************************************
644 * Decode an OS/2 Operating System Error Code
645 *
646 * A convenience function to lookup an OS/2 error code and return a
647 * text message we can use to raise a Python exception.
648 *
649 * Notes:
650 * The messages for errors returned from the OS/2 kernel reside in
651 * the file OSO001.MSG in the \OS2 directory hierarchy.
652 *
653 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000654static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000655os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
656{
657 APIRET rc;
658 ULONG msglen;
659
660 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
661 Py_BEGIN_ALLOW_THREADS
662 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
663 errorcode, "oso001.msg", &msglen);
664 Py_END_ALLOW_THREADS
665
666 if (rc == NO_ERROR)
667 os2_formatmsg(msgbuf, msglen, reason);
668 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000669 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000670 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000671
672 return msgbuf;
673}
674
675/* Set an OS/2-specific error and return NULL. OS/2 kernel
676 errors are not in a global variable e.g. 'errno' nor are
677 they congruent with posix error numbers. */
678
Victor Stinner8c62be82010-05-06 00:08:46 +0000679static PyObject *
680os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000681{
682 char text[1024];
683 PyObject *v;
684
685 os2_strerror(text, sizeof(text), code, "");
686
687 v = Py_BuildValue("(is)", code, text);
688 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000689 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000690 Py_DECREF(v);
691 }
692 return NULL; /* Signal to Python that an Exception is Pending */
693}
694
695#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000696
697/* POSIX generic methods */
698
Barry Warsaw53699e91996-12-10 23:23:01 +0000699static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000700posix_fildes(PyObject *fdobj, int (*func)(int))
701{
Victor Stinner8c62be82010-05-06 00:08:46 +0000702 int fd;
703 int res;
704 fd = PyObject_AsFileDescriptor(fdobj);
705 if (fd < 0)
706 return NULL;
707 if (!_PyVerify_fd(fd))
708 return posix_error();
709 Py_BEGIN_ALLOW_THREADS
710 res = (*func)(fd);
711 Py_END_ALLOW_THREADS
712 if (res < 0)
713 return posix_error();
714 Py_INCREF(Py_None);
715 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000716}
Guido van Rossum21142a01999-01-08 21:05:37 +0000717
718static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000719posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000720{
Victor Stinner8c62be82010-05-06 00:08:46 +0000721 PyObject *opath1 = NULL;
722 char *path1;
723 int res;
724 if (!PyArg_ParseTuple(args, format,
725 PyUnicode_FSConverter, &opath1))
726 return NULL;
727 path1 = PyBytes_AsString(opath1);
728 Py_BEGIN_ALLOW_THREADS
729 res = (*func)(path1);
730 Py_END_ALLOW_THREADS
731 if (res < 0)
732 return posix_error_with_allocated_filename(opath1);
733 Py_DECREF(opath1);
734 Py_INCREF(Py_None);
735 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000736}
737
Barry Warsaw53699e91996-12-10 23:23:01 +0000738static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000739posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000740 char *format,
741 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000742{
Victor Stinner8c62be82010-05-06 00:08:46 +0000743 PyObject *opath1 = NULL, *opath2 = NULL;
744 char *path1, *path2;
745 int res;
746 if (!PyArg_ParseTuple(args, format,
747 PyUnicode_FSConverter, &opath1,
748 PyUnicode_FSConverter, &opath2)) {
749 return NULL;
750 }
751 path1 = PyBytes_AsString(opath1);
752 path2 = PyBytes_AsString(opath2);
753 Py_BEGIN_ALLOW_THREADS
754 res = (*func)(path1, path2);
755 Py_END_ALLOW_THREADS
756 Py_DECREF(opath1);
757 Py_DECREF(opath2);
758 if (res != 0)
759 /* XXX how to report both path1 and path2??? */
760 return posix_error();
761 Py_INCREF(Py_None);
762 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000763}
764
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000765#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000766static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000767win32_1str(PyObject* args, char* func,
768 char* format, BOOL (__stdcall *funcA)(LPCSTR),
769 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000770{
Victor Stinner8c62be82010-05-06 00:08:46 +0000771 PyObject *uni;
772 char *ansi;
773 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000774
Victor Stinner8c62be82010-05-06 00:08:46 +0000775 if (!PyArg_ParseTuple(args, wformat, &uni))
776 PyErr_Clear();
777 else {
778 Py_BEGIN_ALLOW_THREADS
779 result = funcW(PyUnicode_AsUnicode(uni));
780 Py_END_ALLOW_THREADS
781 if (!result)
782 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
783 Py_INCREF(Py_None);
784 return Py_None;
785 }
786 if (!PyArg_ParseTuple(args, format, &ansi))
787 return NULL;
788 Py_BEGIN_ALLOW_THREADS
789 result = funcA(ansi);
790 Py_END_ALLOW_THREADS
791 if (!result)
792 return win32_error(func, ansi);
793 Py_INCREF(Py_None);
794 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000795
796}
797
798/* This is a reimplementation of the C library's chdir function,
799 but one that produces Win32 errors instead of DOS error codes.
800 chdir is essentially a wrapper around SetCurrentDirectory; however,
801 it also needs to set "magic" environment variables indicating
802 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000803static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000804win32_chdir(LPCSTR path)
805{
Victor Stinner8c62be82010-05-06 00:08:46 +0000806 char new_path[MAX_PATH+1];
807 int result;
808 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000809
Victor Stinner8c62be82010-05-06 00:08:46 +0000810 if(!SetCurrentDirectoryA(path))
811 return FALSE;
812 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
813 if (!result)
814 return FALSE;
815 /* In the ANSI API, there should not be any paths longer
816 than MAX_PATH. */
817 assert(result <= MAX_PATH+1);
818 if (strncmp(new_path, "\\\\", 2) == 0 ||
819 strncmp(new_path, "//", 2) == 0)
820 /* UNC path, nothing to do. */
821 return TRUE;
822 env[1] = new_path[0];
823 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000824}
825
826/* The Unicode version differs from the ANSI version
827 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000828static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000829win32_wchdir(LPCWSTR path)
830{
Victor Stinner8c62be82010-05-06 00:08:46 +0000831 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
832 int result;
833 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000834
Victor Stinner8c62be82010-05-06 00:08:46 +0000835 if(!SetCurrentDirectoryW(path))
836 return FALSE;
837 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
838 if (!result)
839 return FALSE;
840 if (result > MAX_PATH+1) {
841 new_path = malloc(result * sizeof(wchar_t));
842 if (!new_path) {
843 SetLastError(ERROR_OUTOFMEMORY);
844 return FALSE;
845 }
846 result = GetCurrentDirectoryW(result, new_path);
847 if (!result) {
848 free(new_path);
849 return FALSE;
850 }
851 }
852 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
853 wcsncmp(new_path, L"//", 2) == 0)
854 /* UNC path, nothing to do. */
855 return TRUE;
856 env[1] = new_path[0];
857 result = SetEnvironmentVariableW(env, new_path);
858 if (new_path != _new_path)
859 free(new_path);
860 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000861}
862#endif
863
Martin v. Löwis14694662006-02-03 12:54:16 +0000864#ifdef MS_WINDOWS
865/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
866 - time stamps are restricted to second resolution
867 - file modification times suffer from forth-and-back conversions between
868 UTC and local time
869 Therefore, we implement our own stat, based on the Win32 API directly.
870*/
Victor Stinner8c62be82010-05-06 00:08:46 +0000871#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000872
873struct win32_stat{
874 int st_dev;
875 __int64 st_ino;
876 unsigned short st_mode;
877 int st_nlink;
878 int st_uid;
879 int st_gid;
880 int st_rdev;
881 __int64 st_size;
882 int st_atime;
883 int st_atime_nsec;
884 int st_mtime;
885 int st_mtime_nsec;
886 int st_ctime;
887 int st_ctime_nsec;
888};
889
890static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
891
892static void
893FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
894{
Victor Stinner8c62be82010-05-06 00:08:46 +0000895 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
896 /* Cannot simply cast and dereference in_ptr,
897 since it might not be aligned properly */
898 __int64 in;
899 memcpy(&in, in_ptr, sizeof(in));
900 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
901 /* XXX Win32 supports time stamps past 2038; we currently don't */
902 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
Martin v. Löwis14694662006-02-03 12:54:16 +0000903}
904
Thomas Wouters477c8d52006-05-27 19:21:47 +0000905static void
906time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
907{
Victor Stinner8c62be82010-05-06 00:08:46 +0000908 /* XXX endianness */
909 __int64 out;
910 out = time_in + secs_between_epochs;
911 out = out * 10000000 + nsec_in / 100;
912 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000913}
914
Martin v. Löwis14694662006-02-03 12:54:16 +0000915/* Below, we *know* that ugo+r is 0444 */
916#if _S_IREAD != 0400
917#error Unsupported C library
918#endif
919static int
920attributes_to_mode(DWORD attr)
921{
Victor Stinner8c62be82010-05-06 00:08:46 +0000922 int m = 0;
923 if (attr & FILE_ATTRIBUTE_DIRECTORY)
924 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
925 else
926 m |= _S_IFREG;
927 if (attr & FILE_ATTRIBUTE_READONLY)
928 m |= 0444;
929 else
930 m |= 0666;
931 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +0000932}
933
934static int
935attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
936{
Victor Stinner8c62be82010-05-06 00:08:46 +0000937 memset(result, 0, sizeof(*result));
938 result->st_mode = attributes_to_mode(info->dwFileAttributes);
939 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
940 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
941 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
942 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +0000943
Victor Stinner8c62be82010-05-06 00:08:46 +0000944 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +0000945}
946
Guido van Rossumd8faa362007-04-27 19:54:29 +0000947static BOOL
948attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
949{
Victor Stinner8c62be82010-05-06 00:08:46 +0000950 HANDLE hFindFile;
951 WIN32_FIND_DATAA FileData;
952 hFindFile = FindFirstFileA(pszFile, &FileData);
953 if (hFindFile == INVALID_HANDLE_VALUE)
954 return FALSE;
955 FindClose(hFindFile);
956 pfad->dwFileAttributes = FileData.dwFileAttributes;
957 pfad->ftCreationTime = FileData.ftCreationTime;
958 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
959 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
960 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
961 pfad->nFileSizeLow = FileData.nFileSizeLow;
962 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000963}
964
965static BOOL
966attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
967{
Victor Stinner8c62be82010-05-06 00:08:46 +0000968 HANDLE hFindFile;
969 WIN32_FIND_DATAW FileData;
970 hFindFile = FindFirstFileW(pszFile, &FileData);
971 if (hFindFile == INVALID_HANDLE_VALUE)
972 return FALSE;
973 FindClose(hFindFile);
974 pfad->dwFileAttributes = FileData.dwFileAttributes;
975 pfad->ftCreationTime = FileData.ftCreationTime;
976 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
977 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
978 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
979 pfad->nFileSizeLow = FileData.nFileSizeLow;
980 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000981}
982
Brian Curtind40e6f72010-07-08 21:39:08 +0000983/* About the following functions: win32_lstat, win32_lstat_w, win32_stat,
984 win32_stat_w
985
986 In Posix, stat automatically traverses symlinks and returns the stat
987 structure for the target. In Windows, the equivalent GetFileAttributes by
988 default does not traverse symlinks and instead returns attributes for
989 the symlink.
990
991 Therefore, win32_lstat will get the attributes traditionally, and
992 win32_stat will first explicitly resolve the symlink target and then will
993 call win32_lstat on that result.
994
995 The _w represent Unicode equivalents of the aformentioned ANSI functions. */
996
997static int
998win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +0000999{
Victor Stinner8c62be82010-05-06 00:08:46 +00001000 WIN32_FILE_ATTRIBUTE_DATA info;
1001 int code;
1002 char *dot;
Brian Curtind40e6f72010-07-08 21:39:08 +00001003 WIN32_FIND_DATAA find_data;
1004 HANDLE find_data_handle;
Victor Stinner8c62be82010-05-06 00:08:46 +00001005 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1006 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1007 /* Protocol violation: we explicitly clear errno, instead of
1008 setting it to a POSIX error. Callers should use GetLastError. */
1009 errno = 0;
1010 return -1;
1011 } else {
1012 /* Could not get attributes on open file. Fall back to
1013 reading the directory. */
1014 if (!attributes_from_dir(path, &info)) {
1015 /* Very strange. This should not fail now */
1016 errno = 0;
1017 return -1;
1018 }
1019 }
1020 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001021
Victor Stinner8c62be82010-05-06 00:08:46 +00001022 code = attribute_data_to_stat(&info, result);
1023 if (code != 0)
1024 return code;
Brian Curtind40e6f72010-07-08 21:39:08 +00001025
1026 /* Get WIN32_FIND_DATA structure for the path to determine if
1027 it is a symlink */
1028 if(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1029 find_data_handle = FindFirstFileA(path, &find_data);
1030 if(find_data_handle != INVALID_HANDLE_VALUE) {
1031 if(find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
1032 /* first clear the S_IFMT bits */
1033 result->st_mode ^= (result->st_mode & 0170000);
1034 /* now set the bits that make this a symlink */
1035 result->st_mode |= 0120000;
1036 }
1037 FindClose(find_data_handle);
1038 }
1039 }
1040
Victor Stinner8c62be82010-05-06 00:08:46 +00001041 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1042 dot = strrchr(path, '.');
1043 if (dot) {
Brian Curtind40e6f72010-07-08 21:39:08 +00001044 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1045 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00001046 result->st_mode |= 0111;
1047 }
1048 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001049}
1050
Victor Stinner8c62be82010-05-06 00:08:46 +00001051static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001052win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001053{
Victor Stinner8c62be82010-05-06 00:08:46 +00001054 int code;
1055 const wchar_t *dot;
1056 WIN32_FILE_ATTRIBUTE_DATA info;
Brian Curtind40e6f72010-07-08 21:39:08 +00001057 WIN32_FIND_DATAW find_data;
1058 HANDLE find_data_handle;
Victor Stinner8c62be82010-05-06 00:08:46 +00001059 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1060 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1061 /* Protocol violation: we explicitly clear errno, instead of
1062 setting it to a POSIX error. Callers should use GetLastError. */
1063 errno = 0;
1064 return -1;
1065 } else {
Brian Curtind40e6f72010-07-08 21:39:08 +00001066 /* Could not get attributes on open file. Fall back to reading
1067 the directory. */
1068 if (!attributes_from_dir_w(path, &info)) {
1069 /* Very strange. This should not fail now */
1070 errno = 0;
1071 return -1;
1072 }
1073 }
1074 }
1075 code = attribute_data_to_stat(&info, result);
1076 if (code < 0)
1077 return code;
1078
1079 /* Get WIN32_FIND_DATA structure for the path to determine if
1080 it is a symlink */
1081 if(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1082 find_data_handle = FindFirstFileW(path, &find_data);
1083 if(find_data_handle != INVALID_HANDLE_VALUE) {
1084 if(find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
1085 /* first clear the S_IFMT bits */
1086 result->st_mode ^= (result->st_mode & 0170000);
1087 /* now set the bits that make this a symlink */
1088 result->st_mode |= 0120000;
1089 }
1090 FindClose(find_data_handle);
1091 }
1092 }
1093
1094 /* Set IFEXEC if it is an .exe, .bat, ... */
1095 dot = wcsrchr(path, '.');
1096 if (dot) {
1097 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1098 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1099 result->st_mode |= 0111;
1100 }
1101 return code;
1102}
1103
1104/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1105static int has_GetFinalPathNameByHandle = 0;
1106static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1107 DWORD);
1108static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1109 DWORD);
1110static int
1111check_GetFinalPathNameByHandle()
1112{
1113 HINSTANCE hKernel32;
1114 /* only recheck */
1115 if (!has_GetFinalPathNameByHandle)
1116 {
1117 hKernel32 = GetModuleHandle("KERNEL32");
1118 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1119 "GetFinalPathNameByHandleA");
1120 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1121 "GetFinalPathNameByHandleW");
Brian Curtin74e45612010-07-09 15:58:59 +00001122 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1123 Py_GetFinalPathNameByHandleW;
Brian Curtind40e6f72010-07-08 21:39:08 +00001124 }
1125 return has_GetFinalPathNameByHandle;
1126}
1127
1128static int
1129win32_stat(const char* path, struct win32_stat *result)
1130{
1131 /* Traverse the symlink to the target using
1132 GetFinalPathNameByHandle()
1133 */
1134 int code;
1135 HANDLE hFile;
1136 int buf_size;
1137 char *target_path;
1138 int result_length;
1139 WIN32_FILE_ATTRIBUTE_DATA info;
1140
1141 if(!check_GetFinalPathNameByHandle()) {
1142 /* if the OS doesn't have GetFinalPathNameByHandle, it doesn't
1143 have symlinks, so just fall back to the traditional behavior
1144 found in lstat. */
1145 return win32_lstat(path, result);
1146 }
1147
1148 hFile = CreateFileA(
1149 path,
1150 0, /* desired access */
1151 0, /* share mode */
1152 NULL, /* security attributes */
1153 OPEN_EXISTING,
1154 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Antoine Pitrou38425292010-09-21 18:19:07 +00001155 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
Brian Curtind40e6f72010-07-08 21:39:08 +00001156 NULL);
1157
1158 if(hFile == INVALID_HANDLE_VALUE) {
1159 /* Either the target doesn't exist, or we don't have access to
1160 get a handle to it. If the former, we need to return an error.
1161 If the latter, we can use attributes_from_dir. */
1162 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1163 /* Protocol violation: we explicitly clear errno, instead of
1164 setting it to a POSIX error. Callers should use GetLastError. */
1165 errno = 0;
1166 return -1;
1167 } else {
1168 /* Could not get attributes on open file. Fall back to
1169 reading the directory. */
1170 if (!attributes_from_dir(path, &info)) {
1171 /* Very strange. This should not fail now */
1172 errno = 0;
1173 return -1;
1174 }
1175 }
1176 code = attribute_data_to_stat(&info, result);
1177 }
Antoine Pitrou38425292010-09-21 18:19:07 +00001178 else {
1179 /* We have a good handle to the target, use it to determine the target
1180 path name (then we'll call lstat on it). */
1181 buf_size = Py_GetFinalPathNameByHandleA(hFile, 0, 0, VOLUME_NAME_DOS);
1182 if(!buf_size) return -1;
1183 /* Due to a slight discrepancy between GetFinalPathNameByHandleA
1184 and GetFinalPathNameByHandleW, we must allocate one more byte
1185 than reported. */
1186 target_path = (char *)malloc((buf_size+2)*sizeof(char));
1187 result_length = Py_GetFinalPathNameByHandleA(hFile, target_path,
1188 buf_size+1, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00001189
Antoine Pitrou38425292010-09-21 18:19:07 +00001190 if(!result_length) {
1191 free(target_path);
1192 return -1;
1193 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001194
Antoine Pitrou38425292010-09-21 18:19:07 +00001195 if(!CloseHandle(hFile)) {
1196 free(target_path);
1197 return -1;
1198 }
1199
1200 target_path[result_length] = 0;
1201 code = win32_lstat(target_path, result);
1202 free(target_path);
1203 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001204
1205 return code;
1206}
1207
1208static int
1209win32_stat_w(const wchar_t* path, struct win32_stat *result)
1210{
1211 /* Traverse the symlink to the target using GetFinalPathNameByHandle() */
1212 int code;
1213 HANDLE hFile;
1214 int buf_size;
1215 wchar_t *target_path;
1216 int result_length;
1217 WIN32_FILE_ATTRIBUTE_DATA info;
1218
1219 if(!check_GetFinalPathNameByHandle()) {
1220 /* If the OS doesn't have GetFinalPathNameByHandle, it doesn't have
1221 symlinks, so just fall back to the traditional behavior found
1222 in lstat. */
1223 return win32_lstat_w(path, result);
1224 }
1225
1226 hFile = CreateFileW(
1227 path,
1228 0, /* desired access */
1229 0, /* share mode */
1230 NULL, /* security attributes */
1231 OPEN_EXISTING,
1232 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1233 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1234 NULL);
Antoine Pitroub73caab2010-08-09 23:39:31 +00001235
Brian Curtind40e6f72010-07-08 21:39:08 +00001236 if(hFile == INVALID_HANDLE_VALUE) {
1237 /* Either the target doesn't exist, or we don't have access to
1238 get a handle to it. If the former, we need to return an error.
1239 If the latter, we can use attributes_from_dir. */
1240 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1241 /* Protocol violation: we explicitly clear errno, instead of
1242 setting it to a POSIX error. Callers should use GetLastError. */
1243 errno = 0;
1244 return -1;
1245 } else {
Victor Stinner8c62be82010-05-06 00:08:46 +00001246 /* Could not get attributes on open file. Fall back to
1247 reading the directory. */
1248 if (!attributes_from_dir_w(path, &info)) {
1249 /* Very strange. This should not fail now */
1250 errno = 0;
1251 return -1;
1252 }
1253 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001254 code = attribute_data_to_stat(&info, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001255 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001256 else {
1257 /* We have a good handle to the target, use it to determine the target
1258 path name (then we'll call lstat on it). */
1259 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_DOS);
1260 if(!buf_size)
1261 return -1;
1262
1263 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
1264 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
1265 buf_size, VOLUME_NAME_DOS);
1266
Antoine Pitrou38425292010-09-21 18:19:07 +00001267 if(!result_length) {
1268 free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00001269 return -1;
Antoine Pitrou38425292010-09-21 18:19:07 +00001270 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001271
Antoine Pitrou38425292010-09-21 18:19:07 +00001272 if(!CloseHandle(hFile)) {
1273 free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00001274 return -1;
Antoine Pitrou38425292010-09-21 18:19:07 +00001275 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001276
1277 target_path[result_length] = 0;
1278 code = win32_lstat_w(target_path, result);
1279 free(target_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001280 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001281
Victor Stinner8c62be82010-05-06 00:08:46 +00001282 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001283}
1284
1285static int
1286win32_fstat(int file_number, struct win32_stat *result)
1287{
Victor Stinner8c62be82010-05-06 00:08:46 +00001288 BY_HANDLE_FILE_INFORMATION info;
1289 HANDLE h;
1290 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001291
Victor Stinner8c62be82010-05-06 00:08:46 +00001292 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001293
Victor Stinner8c62be82010-05-06 00:08:46 +00001294 /* Protocol violation: we explicitly clear errno, instead of
1295 setting it to a POSIX error. Callers should use GetLastError. */
1296 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001297
Victor Stinner8c62be82010-05-06 00:08:46 +00001298 if (h == INVALID_HANDLE_VALUE) {
1299 /* This is really a C library error (invalid file handle).
1300 We set the Win32 error to the closes one matching. */
1301 SetLastError(ERROR_INVALID_HANDLE);
1302 return -1;
1303 }
1304 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001305
Victor Stinner8c62be82010-05-06 00:08:46 +00001306 type = GetFileType(h);
1307 if (type == FILE_TYPE_UNKNOWN) {
1308 DWORD error = GetLastError();
1309 if (error != 0) {
1310 return -1;
1311 }
1312 /* else: valid but unknown file */
1313 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001314
Victor Stinner8c62be82010-05-06 00:08:46 +00001315 if (type != FILE_TYPE_DISK) {
1316 if (type == FILE_TYPE_CHAR)
1317 result->st_mode = _S_IFCHR;
1318 else if (type == FILE_TYPE_PIPE)
1319 result->st_mode = _S_IFIFO;
1320 return 0;
1321 }
1322
1323 if (!GetFileInformationByHandle(h, &info)) {
1324 return -1;
1325 }
1326
1327 /* similar to stat() */
1328 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1329 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
Brian Curtin74e45612010-07-09 15:58:59 +00001330 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime,
1331 &result->st_ctime_nsec);
1332 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime,
1333 &result->st_mtime_nsec);
1334 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime,
1335 &result->st_atime_nsec);
Victor Stinner8c62be82010-05-06 00:08:46 +00001336 /* specific to fstat() */
1337 result->st_nlink = info.nNumberOfLinks;
1338 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1339 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001340}
1341
1342#endif /* MS_WINDOWS */
1343
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001344PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001345"stat_result: Result from stat or lstat.\n\n\
1346This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001347 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001348or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1349\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001350Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1351or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001352\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001353See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001354
1355static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001356 {"st_mode", "protection bits"},
1357 {"st_ino", "inode"},
1358 {"st_dev", "device"},
1359 {"st_nlink", "number of hard links"},
1360 {"st_uid", "user ID of owner"},
1361 {"st_gid", "group ID of owner"},
1362 {"st_size", "total size, in bytes"},
1363 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1364 {NULL, "integer time of last access"},
1365 {NULL, "integer time of last modification"},
1366 {NULL, "integer time of last change"},
1367 {"st_atime", "time of last access"},
1368 {"st_mtime", "time of last modification"},
1369 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001370#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001371 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001372#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001373#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001374 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001375#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001376#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001377 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001378#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001379#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001380 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001381#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001382#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001383 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001384#endif
1385#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001386 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001387#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001388 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001389};
1390
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001391#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001392#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001393#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001394#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001395#endif
1396
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001397#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001398#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1399#else
1400#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1401#endif
1402
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001403#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001404#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1405#else
1406#define ST_RDEV_IDX ST_BLOCKS_IDX
1407#endif
1408
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001409#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1410#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1411#else
1412#define ST_FLAGS_IDX ST_RDEV_IDX
1413#endif
1414
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001415#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001416#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001417#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001418#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001419#endif
1420
1421#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1422#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1423#else
1424#define ST_BIRTHTIME_IDX ST_GEN_IDX
1425#endif
1426
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001427static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001428 "stat_result", /* name */
1429 stat_result__doc__, /* doc */
1430 stat_result_fields,
1431 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001432};
1433
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001434PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001435"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1436This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001437 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001438or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001439\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001440See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001441
1442static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001443 {"f_bsize", },
1444 {"f_frsize", },
1445 {"f_blocks", },
1446 {"f_bfree", },
1447 {"f_bavail", },
1448 {"f_files", },
1449 {"f_ffree", },
1450 {"f_favail", },
1451 {"f_flag", },
1452 {"f_namemax",},
1453 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001454};
1455
1456static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001457 "statvfs_result", /* name */
1458 statvfs_result__doc__, /* doc */
1459 statvfs_result_fields,
1460 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001461};
1462
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001463static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001464static PyTypeObject StatResultType;
1465static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001466static newfunc structseq_new;
1467
1468static PyObject *
1469statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1470{
Victor Stinner8c62be82010-05-06 00:08:46 +00001471 PyStructSequence *result;
1472 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001473
Victor Stinner8c62be82010-05-06 00:08:46 +00001474 result = (PyStructSequence*)structseq_new(type, args, kwds);
1475 if (!result)
1476 return NULL;
1477 /* If we have been initialized from a tuple,
1478 st_?time might be set to None. Initialize it
1479 from the int slots. */
1480 for (i = 7; i <= 9; i++) {
1481 if (result->ob_item[i+3] == Py_None) {
1482 Py_DECREF(Py_None);
1483 Py_INCREF(result->ob_item[i]);
1484 result->ob_item[i+3] = result->ob_item[i];
1485 }
1486 }
1487 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001488}
1489
1490
1491
1492/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001493static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001494
1495PyDoc_STRVAR(stat_float_times__doc__,
1496"stat_float_times([newval]) -> oldval\n\n\
1497Determine whether os.[lf]stat represents time stamps as float objects.\n\
1498If newval is True, future calls to stat() return floats, if it is False,\n\
1499future calls return ints. \n\
1500If newval is omitted, return the current setting.\n");
1501
1502static PyObject*
1503stat_float_times(PyObject* self, PyObject *args)
1504{
Victor Stinner8c62be82010-05-06 00:08:46 +00001505 int newval = -1;
1506 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1507 return NULL;
1508 if (newval == -1)
1509 /* Return old value */
1510 return PyBool_FromLong(_stat_float_times);
1511 _stat_float_times = newval;
1512 Py_INCREF(Py_None);
1513 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001514}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001515
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001516static void
1517fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1518{
Victor Stinner8c62be82010-05-06 00:08:46 +00001519 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001520#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001521 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001522#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001523 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001524#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001525 if (!ival)
1526 return;
1527 if (_stat_float_times) {
1528 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1529 } else {
1530 fval = ival;
1531 Py_INCREF(fval);
1532 }
1533 PyStructSequence_SET_ITEM(v, index, ival);
1534 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001535}
1536
Tim Peters5aa91602002-01-30 05:46:57 +00001537/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001538 (used by posix_stat() and posix_fstat()) */
1539static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001540_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001541{
Victor Stinner8c62be82010-05-06 00:08:46 +00001542 unsigned long ansec, mnsec, cnsec;
1543 PyObject *v = PyStructSequence_New(&StatResultType);
1544 if (v == NULL)
1545 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001546
Victor Stinner8c62be82010-05-06 00:08:46 +00001547 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001548#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001549 PyStructSequence_SET_ITEM(v, 1,
1550 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001551#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001552 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001553#endif
1554#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001555 PyStructSequence_SET_ITEM(v, 2,
1556 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001557#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001558 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001559#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001560 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1561 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1562 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001563#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001564 PyStructSequence_SET_ITEM(v, 6,
1565 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001566#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001567 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001568#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001569
Martin v. Löwis14694662006-02-03 12:54:16 +00001570#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001571 ansec = st->st_atim.tv_nsec;
1572 mnsec = st->st_mtim.tv_nsec;
1573 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001574#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001575 ansec = st->st_atimespec.tv_nsec;
1576 mnsec = st->st_mtimespec.tv_nsec;
1577 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001578#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001579 ansec = st->st_atime_nsec;
1580 mnsec = st->st_mtime_nsec;
1581 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001582#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001583 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001584#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001585 fill_time(v, 7, st->st_atime, ansec);
1586 fill_time(v, 8, st->st_mtime, mnsec);
1587 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001588
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001589#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001590 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1591 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001592#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001593#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001594 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1595 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001596#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001597#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001598 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1599 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001600#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001601#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001602 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1603 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001604#endif
1605#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001606 {
1607 PyObject *val;
1608 unsigned long bsec,bnsec;
1609 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001610#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001611 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001612#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001613 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001614#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001615 if (_stat_float_times) {
1616 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1617 } else {
1618 val = PyLong_FromLong((long)bsec);
1619 }
1620 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1621 val);
1622 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001623#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001624#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001625 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1626 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001627#endif
Fred Drake699f3522000-06-29 21:12:41 +00001628
Victor Stinner8c62be82010-05-06 00:08:46 +00001629 if (PyErr_Occurred()) {
1630 Py_DECREF(v);
1631 return NULL;
1632 }
Fred Drake699f3522000-06-29 21:12:41 +00001633
Victor Stinner8c62be82010-05-06 00:08:46 +00001634 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001635}
1636
Barry Warsaw53699e91996-12-10 23:23:01 +00001637static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001638posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001639 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001640#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001641 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001642#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001643 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001644#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001645 char *wformat,
1646 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001647{
Victor Stinner8c62be82010-05-06 00:08:46 +00001648 STRUCT_STAT st;
1649 PyObject *opath;
1650 char *path;
1651 int res;
1652 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001653
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001654#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001655 PyUnicodeObject *po;
1656 if (PyArg_ParseTuple(args, wformat, &po)) {
1657 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001658
Victor Stinner8c62be82010-05-06 00:08:46 +00001659 Py_BEGIN_ALLOW_THREADS
1660 /* PyUnicode_AS_UNICODE result OK without
1661 thread lock as it is a simple dereference. */
1662 res = wstatfunc(wpath, &st);
1663 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001664
Victor Stinner8c62be82010-05-06 00:08:46 +00001665 if (res != 0)
1666 return win32_error_unicode("stat", wpath);
1667 return _pystat_fromstructstat(&st);
1668 }
1669 /* Drop the argument parsing error as narrow strings
1670 are also valid. */
1671 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001672#endif
1673
Victor Stinner8c62be82010-05-06 00:08:46 +00001674 if (!PyArg_ParseTuple(args, format,
1675 PyUnicode_FSConverter, &opath))
1676 return NULL;
1677 path = PyBytes_AsString(opath);
1678 Py_BEGIN_ALLOW_THREADS
1679 res = (*statfunc)(path, &st);
1680 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001681
Victor Stinner8c62be82010-05-06 00:08:46 +00001682 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001683#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001684 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001685#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001686 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001687#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001688 }
1689 else
1690 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001691
Victor Stinner8c62be82010-05-06 00:08:46 +00001692 Py_DECREF(opath);
1693 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001694}
1695
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001696/* POSIX methods */
1697
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001698PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001699"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001700Use the real uid/gid to test for access to a path. Note that most\n\
1701operations will use the effective uid/gid, therefore this routine can\n\
1702be used in a suid/sgid environment to test if the invoking user has the\n\
1703specified access to the path. The mode argument can be F_OK to test\n\
1704existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001705
1706static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001707posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001708{
Victor Stinner8c62be82010-05-06 00:08:46 +00001709 PyObject *opath;
1710 char *path;
1711 int mode;
1712
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001713#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001714 DWORD attr;
1715 PyUnicodeObject *po;
1716 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1717 Py_BEGIN_ALLOW_THREADS
1718 /* PyUnicode_AS_UNICODE OK without thread lock as
1719 it is a simple dereference. */
1720 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1721 Py_END_ALLOW_THREADS
1722 goto finish;
1723 }
1724 /* Drop the argument parsing error as narrow strings
1725 are also valid. */
1726 PyErr_Clear();
1727 if (!PyArg_ParseTuple(args, "O&i:access",
1728 PyUnicode_FSConverter, &opath, &mode))
1729 return NULL;
1730 path = PyBytes_AsString(opath);
1731 Py_BEGIN_ALLOW_THREADS
1732 attr = GetFileAttributesA(path);
1733 Py_END_ALLOW_THREADS
1734 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001735finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001736 if (attr == 0xFFFFFFFF)
1737 /* File does not exist, or cannot read attributes */
1738 return PyBool_FromLong(0);
1739 /* Access is possible if either write access wasn't requested, or
1740 the file isn't read-only, or if it's a directory, as there are
1741 no read-only directories on Windows. */
1742 return PyBool_FromLong(!(mode & 2)
1743 || !(attr & FILE_ATTRIBUTE_READONLY)
1744 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001745#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001746 int res;
1747 if (!PyArg_ParseTuple(args, "O&i:access",
1748 PyUnicode_FSConverter, &opath, &mode))
1749 return NULL;
1750 path = PyBytes_AsString(opath);
1751 Py_BEGIN_ALLOW_THREADS
1752 res = access(path, mode);
1753 Py_END_ALLOW_THREADS
1754 Py_DECREF(opath);
1755 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001756#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001757}
1758
Guido van Rossumd371ff11999-01-25 16:12:23 +00001759#ifndef F_OK
1760#define F_OK 0
1761#endif
1762#ifndef R_OK
1763#define R_OK 4
1764#endif
1765#ifndef W_OK
1766#define W_OK 2
1767#endif
1768#ifndef X_OK
1769#define X_OK 1
1770#endif
1771
1772#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001773PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001774"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001775Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001776
1777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001778posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001779{
Victor Stinner8c62be82010-05-06 00:08:46 +00001780 int id;
1781 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001782
Victor Stinner8c62be82010-05-06 00:08:46 +00001783 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1784 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001785
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001786#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001787 /* file descriptor 0 only, the default input device (stdin) */
1788 if (id == 0) {
1789 ret = ttyname();
1790 }
1791 else {
1792 ret = NULL;
1793 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001794#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001795 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001796#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001797 if (ret == NULL)
1798 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001799 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001800}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001801#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001802
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001803#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001804PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001805"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001806Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001807
1808static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001809posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001810{
Victor Stinner8c62be82010-05-06 00:08:46 +00001811 char *ret;
1812 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001813
Greg Wardb48bc172000-03-01 21:51:56 +00001814#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001815 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001816#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001817 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001818#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001819 if (ret == NULL)
1820 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001821 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001822}
1823#endif
1824
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001825PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001826"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001827Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001828
Barry Warsaw53699e91996-12-10 23:23:01 +00001829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001830posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001831{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001832#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001833 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001834#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001835 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001836#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001837 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001838#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001839 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001840#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001841}
1842
Fred Drake4d1e64b2002-04-15 19:40:07 +00001843#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001844PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001845"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001846Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001847opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001848
1849static PyObject *
1850posix_fchdir(PyObject *self, PyObject *fdobj)
1851{
Victor Stinner8c62be82010-05-06 00:08:46 +00001852 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001853}
1854#endif /* HAVE_FCHDIR */
1855
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001856
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001857PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001858"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001859Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001860
Barry Warsaw53699e91996-12-10 23:23:01 +00001861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001862posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001863{
Victor Stinner8c62be82010-05-06 00:08:46 +00001864 PyObject *opath = NULL;
1865 char *path = NULL;
1866 int i;
1867 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001868#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001869 DWORD attr;
1870 PyUnicodeObject *po;
1871 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1872 Py_BEGIN_ALLOW_THREADS
1873 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1874 if (attr != 0xFFFFFFFF) {
1875 if (i & _S_IWRITE)
1876 attr &= ~FILE_ATTRIBUTE_READONLY;
1877 else
1878 attr |= FILE_ATTRIBUTE_READONLY;
1879 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1880 }
1881 else
1882 res = 0;
1883 Py_END_ALLOW_THREADS
1884 if (!res)
1885 return win32_error_unicode("chmod",
1886 PyUnicode_AS_UNICODE(po));
1887 Py_INCREF(Py_None);
1888 return Py_None;
1889 }
1890 /* Drop the argument parsing error as narrow strings
1891 are also valid. */
1892 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001893
Victor Stinner8c62be82010-05-06 00:08:46 +00001894 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1895 &opath, &i))
1896 return NULL;
1897 path = PyBytes_AsString(opath);
1898 Py_BEGIN_ALLOW_THREADS
1899 attr = GetFileAttributesA(path);
1900 if (attr != 0xFFFFFFFF) {
1901 if (i & _S_IWRITE)
1902 attr &= ~FILE_ATTRIBUTE_READONLY;
1903 else
1904 attr |= FILE_ATTRIBUTE_READONLY;
1905 res = SetFileAttributesA(path, attr);
1906 }
1907 else
1908 res = 0;
1909 Py_END_ALLOW_THREADS
1910 if (!res) {
1911 win32_error("chmod", path);
1912 Py_DECREF(opath);
1913 return NULL;
1914 }
1915 Py_DECREF(opath);
1916 Py_INCREF(Py_None);
1917 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001918#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00001919 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1920 &opath, &i))
1921 return NULL;
1922 path = PyBytes_AsString(opath);
1923 Py_BEGIN_ALLOW_THREADS
1924 res = chmod(path, i);
1925 Py_END_ALLOW_THREADS
1926 if (res < 0)
1927 return posix_error_with_allocated_filename(opath);
1928 Py_DECREF(opath);
1929 Py_INCREF(Py_None);
1930 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001931#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001932}
1933
Christian Heimes4e30a842007-11-30 22:12:06 +00001934#ifdef HAVE_FCHMOD
1935PyDoc_STRVAR(posix_fchmod__doc__,
1936"fchmod(fd, mode)\n\n\
1937Change the access permissions of the file given by file\n\
1938descriptor fd.");
1939
1940static PyObject *
1941posix_fchmod(PyObject *self, PyObject *args)
1942{
Victor Stinner8c62be82010-05-06 00:08:46 +00001943 int fd, mode, res;
1944 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1945 return NULL;
1946 Py_BEGIN_ALLOW_THREADS
1947 res = fchmod(fd, mode);
1948 Py_END_ALLOW_THREADS
1949 if (res < 0)
1950 return posix_error();
1951 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001952}
1953#endif /* HAVE_FCHMOD */
1954
1955#ifdef HAVE_LCHMOD
1956PyDoc_STRVAR(posix_lchmod__doc__,
1957"lchmod(path, mode)\n\n\
1958Change the access permissions of a file. If path is a symlink, this\n\
1959affects the link itself rather than the target.");
1960
1961static PyObject *
1962posix_lchmod(PyObject *self, PyObject *args)
1963{
Victor Stinner8c62be82010-05-06 00:08:46 +00001964 PyObject *opath;
1965 char *path;
1966 int i;
1967 int res;
1968 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
1969 &opath, &i))
1970 return NULL;
1971 path = PyBytes_AsString(opath);
1972 Py_BEGIN_ALLOW_THREADS
1973 res = lchmod(path, i);
1974 Py_END_ALLOW_THREADS
1975 if (res < 0)
1976 return posix_error_with_allocated_filename(opath);
1977 Py_DECREF(opath);
1978 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001979}
1980#endif /* HAVE_LCHMOD */
1981
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001982
Thomas Wouterscf297e42007-02-23 15:07:44 +00001983#ifdef HAVE_CHFLAGS
1984PyDoc_STRVAR(posix_chflags__doc__,
1985"chflags(path, flags)\n\n\
1986Set file flags.");
1987
1988static PyObject *
1989posix_chflags(PyObject *self, PyObject *args)
1990{
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 PyObject *opath;
1992 char *path;
1993 unsigned long flags;
1994 int res;
1995 if (!PyArg_ParseTuple(args, "O&k:chflags",
1996 PyUnicode_FSConverter, &opath, &flags))
1997 return NULL;
1998 path = PyBytes_AsString(opath);
1999 Py_BEGIN_ALLOW_THREADS
2000 res = chflags(path, flags);
2001 Py_END_ALLOW_THREADS
2002 if (res < 0)
2003 return posix_error_with_allocated_filename(opath);
2004 Py_DECREF(opath);
2005 Py_INCREF(Py_None);
2006 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002007}
2008#endif /* HAVE_CHFLAGS */
2009
2010#ifdef HAVE_LCHFLAGS
2011PyDoc_STRVAR(posix_lchflags__doc__,
2012"lchflags(path, flags)\n\n\
2013Set file flags.\n\
2014This function will not follow symbolic links.");
2015
2016static PyObject *
2017posix_lchflags(PyObject *self, PyObject *args)
2018{
Victor Stinner8c62be82010-05-06 00:08:46 +00002019 PyObject *opath;
2020 char *path;
2021 unsigned long flags;
2022 int res;
2023 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2024 PyUnicode_FSConverter, &opath, &flags))
2025 return NULL;
2026 path = PyBytes_AsString(opath);
2027 Py_BEGIN_ALLOW_THREADS
2028 res = lchflags(path, flags);
2029 Py_END_ALLOW_THREADS
2030 if (res < 0)
2031 return posix_error_with_allocated_filename(opath);
2032 Py_DECREF(opath);
2033 Py_INCREF(Py_None);
2034 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002035}
2036#endif /* HAVE_LCHFLAGS */
2037
Martin v. Löwis244edc82001-10-04 22:44:26 +00002038#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002039PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002040"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002041Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002042
2043static PyObject *
2044posix_chroot(PyObject *self, PyObject *args)
2045{
Victor Stinner8c62be82010-05-06 00:08:46 +00002046 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002047}
2048#endif
2049
Guido van Rossum21142a01999-01-08 21:05:37 +00002050#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002051PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002052"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002053force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002054
2055static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002056posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002057{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002058 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002059}
2060#endif /* HAVE_FSYNC */
2061
2062#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002063
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002064#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002065extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2066#endif
2067
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002068PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002069"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002070force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002071 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002072
2073static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002074posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002075{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002076 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002077}
2078#endif /* HAVE_FDATASYNC */
2079
2080
Fredrik Lundh10723342000-07-10 16:38:09 +00002081#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002082PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002083"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002084Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002085
Barry Warsaw53699e91996-12-10 23:23:01 +00002086static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002087posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002088{
Victor Stinner8c62be82010-05-06 00:08:46 +00002089 PyObject *opath;
2090 char *path;
2091 long uid, gid;
2092 int res;
2093 if (!PyArg_ParseTuple(args, "O&ll:chown",
2094 PyUnicode_FSConverter, &opath,
2095 &uid, &gid))
2096 return NULL;
2097 path = PyBytes_AsString(opath);
2098 Py_BEGIN_ALLOW_THREADS
2099 res = chown(path, (uid_t) uid, (gid_t) gid);
2100 Py_END_ALLOW_THREADS
2101 if (res < 0)
2102 return posix_error_with_allocated_filename(opath);
2103 Py_DECREF(opath);
2104 Py_INCREF(Py_None);
2105 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002106}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002107#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002108
Christian Heimes4e30a842007-11-30 22:12:06 +00002109#ifdef HAVE_FCHOWN
2110PyDoc_STRVAR(posix_fchown__doc__,
2111"fchown(fd, uid, gid)\n\n\
2112Change the owner and group id of the file given by file descriptor\n\
2113fd to the numeric uid and gid.");
2114
2115static PyObject *
2116posix_fchown(PyObject *self, PyObject *args)
2117{
Victor Stinner8c62be82010-05-06 00:08:46 +00002118 int fd;
2119 long uid, gid;
2120 int res;
2121 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2122 return NULL;
2123 Py_BEGIN_ALLOW_THREADS
2124 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2125 Py_END_ALLOW_THREADS
2126 if (res < 0)
2127 return posix_error();
2128 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002129}
2130#endif /* HAVE_FCHOWN */
2131
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002132#ifdef HAVE_LCHOWN
2133PyDoc_STRVAR(posix_lchown__doc__,
2134"lchown(path, uid, gid)\n\n\
2135Change the owner and group id of path to the numeric uid and gid.\n\
2136This function will not follow symbolic links.");
2137
2138static PyObject *
2139posix_lchown(PyObject *self, PyObject *args)
2140{
Victor Stinner8c62be82010-05-06 00:08:46 +00002141 PyObject *opath;
2142 char *path;
2143 long uid, gid;
2144 int res;
2145 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2146 PyUnicode_FSConverter, &opath,
2147 &uid, &gid))
2148 return NULL;
2149 path = PyBytes_AsString(opath);
2150 Py_BEGIN_ALLOW_THREADS
2151 res = lchown(path, (uid_t) uid, (gid_t) gid);
2152 Py_END_ALLOW_THREADS
2153 if (res < 0)
2154 return posix_error_with_allocated_filename(opath);
2155 Py_DECREF(opath);
2156 Py_INCREF(Py_None);
2157 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002158}
2159#endif /* HAVE_LCHOWN */
2160
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002161
Guido van Rossum36bc6801995-06-14 22:54:23 +00002162#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002163static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002164posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002165{
Victor Stinner8c62be82010-05-06 00:08:46 +00002166 char buf[1026];
2167 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002168
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002169#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002170 if (!use_bytes) {
2171 wchar_t wbuf[1026];
2172 wchar_t *wbuf2 = wbuf;
2173 PyObject *resobj;
2174 DWORD len;
2175 Py_BEGIN_ALLOW_THREADS
2176 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2177 /* If the buffer is large enough, len does not include the
2178 terminating \0. If the buffer is too small, len includes
2179 the space needed for the terminator. */
2180 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2181 wbuf2 = malloc(len * sizeof(wchar_t));
2182 if (wbuf2)
2183 len = GetCurrentDirectoryW(len, wbuf2);
2184 }
2185 Py_END_ALLOW_THREADS
2186 if (!wbuf2) {
2187 PyErr_NoMemory();
2188 return NULL;
2189 }
2190 if (!len) {
2191 if (wbuf2 != wbuf) free(wbuf2);
2192 return win32_error("getcwdu", NULL);
2193 }
2194 resobj = PyUnicode_FromWideChar(wbuf2, len);
2195 if (wbuf2 != wbuf) free(wbuf2);
2196 return resobj;
2197 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002198#endif
2199
Victor Stinner8c62be82010-05-06 00:08:46 +00002200 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002201#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002202 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002203#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002204 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002205#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002206 Py_END_ALLOW_THREADS
2207 if (res == NULL)
2208 return posix_error();
2209 if (use_bytes)
2210 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002211 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002212}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002213
2214PyDoc_STRVAR(posix_getcwd__doc__,
2215"getcwd() -> path\n\n\
2216Return a unicode string representing the current working directory.");
2217
2218static PyObject *
2219posix_getcwd_unicode(PyObject *self)
2220{
2221 return posix_getcwd(0);
2222}
2223
2224PyDoc_STRVAR(posix_getcwdb__doc__,
2225"getcwdb() -> path\n\n\
2226Return a bytes string representing the current working directory.");
2227
2228static PyObject *
2229posix_getcwd_bytes(PyObject *self)
2230{
2231 return posix_getcwd(1);
2232}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002233#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002234
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002235
Guido van Rossumb6775db1994-08-01 11:34:53 +00002236#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002237PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002238"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002239Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002240
Barry Warsaw53699e91996-12-10 23:23:01 +00002241static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002242posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002243{
Victor Stinner8c62be82010-05-06 00:08:46 +00002244 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002245}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002246#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002247
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002248
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002249PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002250"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002251Return a list containing the names of the entries in the directory.\n\
2252\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002253 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002254\n\
2255The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002256entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002257
Barry Warsaw53699e91996-12-10 23:23:01 +00002258static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002259posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002260{
Victor Stinner8c62be82010-05-06 00:08:46 +00002261 /* XXX Should redo this putting the (now four) versions of opendir
2262 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002263#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002264
Victor Stinner8c62be82010-05-06 00:08:46 +00002265 PyObject *d, *v;
2266 HANDLE hFindFile;
2267 BOOL result;
2268 WIN32_FIND_DATA FileData;
2269 PyObject *opath;
2270 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2271 char *bufptr = namebuf;
2272 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002273
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002274 PyObject *po = NULL;
2275 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002276 WIN32_FIND_DATAW wFileData;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002277 Py_UNICODE *wnamebuf, *po_wchars;
2278
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002279 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002280 po_wchars = L".";
2281 len = 1;
2282 } else {
2283 po_wchars = PyUnicode_AS_UNICODE(po);
2284 len = PyUnicode_GET_SIZE(po);
2285 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002286 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002287 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2288 if (!wnamebuf) {
2289 PyErr_NoMemory();
2290 return NULL;
2291 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002292 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002293 if (len > 0) {
2294 Py_UNICODE wch = wnamebuf[len-1];
2295 if (wch != L'/' && wch != L'\\' && wch != L':')
2296 wnamebuf[len++] = L'\\';
2297 wcscpy(wnamebuf + len, L"*.*");
2298 }
2299 if ((d = PyList_New(0)) == NULL) {
2300 free(wnamebuf);
2301 return NULL;
2302 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002303 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002304 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002305 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002306 if (hFindFile == INVALID_HANDLE_VALUE) {
2307 int error = GetLastError();
2308 if (error == ERROR_FILE_NOT_FOUND) {
2309 free(wnamebuf);
2310 return d;
2311 }
2312 Py_DECREF(d);
2313 win32_error_unicode("FindFirstFileW", wnamebuf);
2314 free(wnamebuf);
2315 return NULL;
2316 }
2317 do {
2318 /* Skip over . and .. */
2319 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2320 wcscmp(wFileData.cFileName, L"..") != 0) {
2321 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2322 if (v == NULL) {
2323 Py_DECREF(d);
2324 d = NULL;
2325 break;
2326 }
2327 if (PyList_Append(d, v) != 0) {
2328 Py_DECREF(v);
2329 Py_DECREF(d);
2330 d = NULL;
2331 break;
2332 }
2333 Py_DECREF(v);
2334 }
2335 Py_BEGIN_ALLOW_THREADS
2336 result = FindNextFileW(hFindFile, &wFileData);
2337 Py_END_ALLOW_THREADS
2338 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2339 it got to the end of the directory. */
2340 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2341 Py_DECREF(d);
2342 win32_error_unicode("FindNextFileW", wnamebuf);
2343 FindClose(hFindFile);
2344 free(wnamebuf);
2345 return NULL;
2346 }
2347 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002348
Victor Stinner8c62be82010-05-06 00:08:46 +00002349 if (FindClose(hFindFile) == FALSE) {
2350 Py_DECREF(d);
2351 win32_error_unicode("FindClose", wnamebuf);
2352 free(wnamebuf);
2353 return NULL;
2354 }
2355 free(wnamebuf);
2356 return d;
2357 }
2358 /* Drop the argument parsing error as narrow strings
2359 are also valid. */
2360 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002361
Victor Stinner8c62be82010-05-06 00:08:46 +00002362 if (!PyArg_ParseTuple(args, "O&:listdir",
2363 PyUnicode_FSConverter, &opath))
2364 return NULL;
2365 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2366 PyErr_SetString(PyExc_ValueError, "path too long");
2367 Py_DECREF(opath);
2368 return NULL;
2369 }
2370 strcpy(namebuf, PyBytes_AsString(opath));
2371 len = PyObject_Size(opath);
2372 if (len > 0) {
2373 char ch = namebuf[len-1];
2374 if (ch != SEP && ch != ALTSEP && ch != ':')
2375 namebuf[len++] = '/';
2376 strcpy(namebuf + len, "*.*");
2377 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002378
Victor Stinner8c62be82010-05-06 00:08:46 +00002379 if ((d = PyList_New(0)) == NULL)
2380 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002381
Antoine Pitroub73caab2010-08-09 23:39:31 +00002382 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002383 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002384 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002385 if (hFindFile == INVALID_HANDLE_VALUE) {
2386 int error = GetLastError();
2387 if (error == ERROR_FILE_NOT_FOUND)
2388 return d;
2389 Py_DECREF(d);
2390 return win32_error("FindFirstFile", namebuf);
2391 }
2392 do {
2393 /* Skip over . and .. */
2394 if (strcmp(FileData.cFileName, ".") != 0 &&
2395 strcmp(FileData.cFileName, "..") != 0) {
2396 v = PyBytes_FromString(FileData.cFileName);
2397 if (v == NULL) {
2398 Py_DECREF(d);
2399 d = NULL;
2400 break;
2401 }
2402 if (PyList_Append(d, v) != 0) {
2403 Py_DECREF(v);
2404 Py_DECREF(d);
2405 d = NULL;
2406 break;
2407 }
2408 Py_DECREF(v);
2409 }
2410 Py_BEGIN_ALLOW_THREADS
2411 result = FindNextFile(hFindFile, &FileData);
2412 Py_END_ALLOW_THREADS
2413 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2414 it got to the end of the directory. */
2415 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2416 Py_DECREF(d);
2417 win32_error("FindNextFile", namebuf);
2418 FindClose(hFindFile);
2419 return NULL;
2420 }
2421 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002422
Victor Stinner8c62be82010-05-06 00:08:46 +00002423 if (FindClose(hFindFile) == FALSE) {
2424 Py_DECREF(d);
2425 return win32_error("FindClose", namebuf);
2426 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002427
Victor Stinner8c62be82010-05-06 00:08:46 +00002428 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002429
Tim Peters0bb44a42000-09-15 07:44:49 +00002430#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002431
2432#ifndef MAX_PATH
2433#define MAX_PATH CCHMAXPATH
2434#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002435 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002436 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002437 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002438 PyObject *d, *v;
2439 char namebuf[MAX_PATH+5];
2440 HDIR hdir = 1;
2441 ULONG srchcnt = 1;
2442 FILEFINDBUF3 ep;
2443 APIRET rc;
2444
Victor Stinner8c62be82010-05-06 00:08:46 +00002445 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002446 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002447 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002448 name = PyBytes_AsString(oname);
2449 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002450 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002451 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002452 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002453 return NULL;
2454 }
2455 strcpy(namebuf, name);
2456 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002457 if (*pt == ALTSEP)
2458 *pt = SEP;
2459 if (namebuf[len-1] != SEP)
2460 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002461 strcpy(namebuf + len, "*.*");
2462
Neal Norwitz6c913782007-10-14 03:23:09 +00002463 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002464 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002465 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002466 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002467
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002468 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2469 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002470 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002471 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2472 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2473 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002474
2475 if (rc != NO_ERROR) {
2476 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002477 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002478 }
2479
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002480 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002481 do {
2482 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002483 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002484 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002485
2486 strcpy(namebuf, ep.achName);
2487
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002488 /* Leave Case of Name Alone -- In Native Form */
2489 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002490
Christian Heimes72b710a2008-05-26 13:28:38 +00002491 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002492 if (v == NULL) {
2493 Py_DECREF(d);
2494 d = NULL;
2495 break;
2496 }
2497 if (PyList_Append(d, v) != 0) {
2498 Py_DECREF(v);
2499 Py_DECREF(d);
2500 d = NULL;
2501 break;
2502 }
2503 Py_DECREF(v);
2504 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2505 }
2506
Victor Stinnerdcb24032010-04-22 12:08:36 +00002507 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002508 return d;
2509#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002510 PyObject *oname;
2511 char *name;
2512 PyObject *d, *v;
2513 DIR *dirp;
2514 struct dirent *ep;
2515 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002516
Victor Stinner8c62be82010-05-06 00:08:46 +00002517 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002518 /* v is never read, so it does not need to be initialized yet. */
2519 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002520 arg_is_unicode = 0;
2521 PyErr_Clear();
2522 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002523 oname = NULL;
2524 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002525 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002526 if (oname == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002527 oname = PyBytes_FromString(".");
2528 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002529 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002530 Py_BEGIN_ALLOW_THREADS
2531 dirp = opendir(name);
2532 Py_END_ALLOW_THREADS
2533 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002534 return posix_error_with_allocated_filename(oname);
2535 }
2536 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002537 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002538 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002539 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002540 Py_DECREF(oname);
2541 return NULL;
2542 }
2543 for (;;) {
2544 errno = 0;
2545 Py_BEGIN_ALLOW_THREADS
2546 ep = readdir(dirp);
2547 Py_END_ALLOW_THREADS
2548 if (ep == NULL) {
2549 if (errno == 0) {
2550 break;
2551 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002552 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002553 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002554 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002555 Py_DECREF(d);
2556 return posix_error_with_allocated_filename(oname);
2557 }
2558 }
2559 if (ep->d_name[0] == '.' &&
2560 (NAMLEN(ep) == 1 ||
2561 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2562 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002563 if (arg_is_unicode)
2564 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2565 else
2566 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002567 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002568 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002569 break;
2570 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002571 if (PyList_Append(d, v) != 0) {
2572 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002573 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002574 break;
2575 }
2576 Py_DECREF(v);
2577 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002578 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002579 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002580 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002581 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002582
Victor Stinner8c62be82010-05-06 00:08:46 +00002583 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002584
Tim Peters0bb44a42000-09-15 07:44:49 +00002585#endif /* which OS */
2586} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002587
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002588#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002589/* A helper function for abspath on win32 */
2590static PyObject *
2591posix__getfullpathname(PyObject *self, PyObject *args)
2592{
Victor Stinner8c62be82010-05-06 00:08:46 +00002593 PyObject *opath;
2594 char *path;
2595 char outbuf[MAX_PATH*2];
2596 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002597#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002598 PyUnicodeObject *po;
2599 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2600 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2601 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2602 Py_UNICODE *wtemp;
2603 DWORD result;
2604 PyObject *v;
2605 result = GetFullPathNameW(wpath,
2606 sizeof(woutbuf)/sizeof(woutbuf[0]),
2607 woutbuf, &wtemp);
2608 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2609 woutbufp = malloc(result * sizeof(Py_UNICODE));
2610 if (!woutbufp)
2611 return PyErr_NoMemory();
2612 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2613 }
2614 if (result)
2615 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2616 else
2617 v = win32_error_unicode("GetFullPathNameW", wpath);
2618 if (woutbufp != woutbuf)
2619 free(woutbufp);
2620 return v;
2621 }
2622 /* Drop the argument parsing error as narrow strings
2623 are also valid. */
2624 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002625
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002626#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002627 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2628 PyUnicode_FSConverter, &opath))
2629 return NULL;
2630 path = PyBytes_AsString(opath);
2631 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2632 outbuf, &temp)) {
2633 win32_error("GetFullPathName", path);
2634 Py_DECREF(opath);
2635 return NULL;
2636 }
2637 Py_DECREF(opath);
2638 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2639 return PyUnicode_Decode(outbuf, strlen(outbuf),
2640 Py_FileSystemDefaultEncoding, NULL);
2641 }
2642 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002643} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002644
2645/* A helper function for samepath on windows */
2646static PyObject *
2647posix__getfinalpathname(PyObject *self, PyObject *args)
2648{
2649 HANDLE hFile;
2650 int buf_size;
2651 wchar_t *target_path;
2652 int result_length;
2653 PyObject *result;
2654 wchar_t *path;
2655
2656 if (!PyArg_ParseTuple(args, "u|:_getfullpathname", &path)) {
2657 return NULL;
2658 }
2659
2660 if(!check_GetFinalPathNameByHandle()) {
2661 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2662 NotImplementedError. */
2663 return PyErr_Format(PyExc_NotImplementedError,
2664 "GetFinalPathNameByHandle not available on this platform");
2665 }
2666
2667 hFile = CreateFileW(
2668 path,
2669 0, /* desired access */
2670 0, /* share mode */
2671 NULL, /* security attributes */
2672 OPEN_EXISTING,
2673 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2674 FILE_FLAG_BACKUP_SEMANTICS,
2675 NULL);
2676
2677 if(hFile == INVALID_HANDLE_VALUE) {
2678 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002679 return PyErr_Format(PyExc_RuntimeError,
2680 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002681 }
2682
2683 /* We have a good handle to the target, use it to determine the
2684 target path name. */
2685 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2686
2687 if(!buf_size)
2688 return win32_error_unicode("GetFinalPathNameByHandle", path);
2689
2690 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2691 if(!target_path)
2692 return PyErr_NoMemory();
2693
2694 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2695 buf_size, VOLUME_NAME_DOS);
2696 if(!result_length)
2697 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2698
2699 if(!CloseHandle(hFile))
2700 return win32_error_unicode("GetFinalPathNameByHandle", path);
2701
2702 target_path[result_length] = 0;
2703 result = PyUnicode_FromUnicode(target_path, result_length);
2704 free(target_path);
2705 return result;
2706
2707} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00002708
2709static PyObject *
2710posix__getfileinformation(PyObject *self, PyObject *args)
2711{
2712 HANDLE hFile;
2713 BY_HANDLE_FILE_INFORMATION info;
2714 int fd;
2715
2716 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
2717 return NULL;
2718
2719 if (!_PyVerify_fd(fd)) {
2720 PyErr_SetString(PyExc_ValueError, "received invalid file descriptor");
2721 return NULL;
2722 }
2723
2724 hFile = (HANDLE)_get_osfhandle(fd);
2725 if (hFile == INVALID_HANDLE_VALUE)
2726 return win32_error("_getfileinformation", NULL);
2727
2728 if (!GetFileInformationByHandle(hFile, &info))
2729 return win32_error("_getfileinformation", NULL);
2730
2731 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
2732 info.nFileIndexHigh,
2733 info.nFileIndexLow);
2734}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002735#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002736
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002737PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002738"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002739Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002740
Barry Warsaw53699e91996-12-10 23:23:01 +00002741static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002742posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002743{
Victor Stinner8c62be82010-05-06 00:08:46 +00002744 int res;
2745 PyObject *opath;
2746 char *path;
2747 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002748
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002749#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002750 PyUnicodeObject *po;
2751 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2752 Py_BEGIN_ALLOW_THREADS
2753 /* PyUnicode_AS_UNICODE OK without thread lock as
2754 it is a simple dereference. */
2755 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2756 Py_END_ALLOW_THREADS
2757 if (!res)
2758 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2759 Py_INCREF(Py_None);
2760 return Py_None;
2761 }
2762 /* Drop the argument parsing error as narrow strings
2763 are also valid. */
2764 PyErr_Clear();
2765 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2766 PyUnicode_FSConverter, &opath, &mode))
2767 return NULL;
2768 path = PyBytes_AsString(opath);
2769 Py_BEGIN_ALLOW_THREADS
2770 /* PyUnicode_AS_UNICODE OK without thread lock as
2771 it is a simple dereference. */
2772 res = CreateDirectoryA(path, NULL);
2773 Py_END_ALLOW_THREADS
2774 if (!res) {
2775 win32_error("mkdir", path);
2776 Py_DECREF(opath);
2777 return NULL;
2778 }
2779 Py_DECREF(opath);
2780 Py_INCREF(Py_None);
2781 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002782#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002783
Victor Stinner8c62be82010-05-06 00:08:46 +00002784 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2785 PyUnicode_FSConverter, &opath, &mode))
2786 return NULL;
2787 path = PyBytes_AsString(opath);
2788 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002789#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002790 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002791#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002792 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002793#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002794 Py_END_ALLOW_THREADS
2795 if (res < 0)
2796 return posix_error_with_allocated_filename(opath);
2797 Py_DECREF(opath);
2798 Py_INCREF(Py_None);
2799 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002800#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002801}
2802
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002803
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002804/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2805#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002806#include <sys/resource.h>
2807#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002808
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002809
2810#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002811PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002812"nice(inc) -> new_priority\n\n\
2813Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002814
Barry Warsaw53699e91996-12-10 23:23:01 +00002815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002816posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002817{
Victor Stinner8c62be82010-05-06 00:08:46 +00002818 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002819
Victor Stinner8c62be82010-05-06 00:08:46 +00002820 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2821 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002822
Victor Stinner8c62be82010-05-06 00:08:46 +00002823 /* There are two flavours of 'nice': one that returns the new
2824 priority (as required by almost all standards out there) and the
2825 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2826 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002827
Victor Stinner8c62be82010-05-06 00:08:46 +00002828 If we are of the nice family that returns the new priority, we
2829 need to clear errno before the call, and check if errno is filled
2830 before calling posix_error() on a returnvalue of -1, because the
2831 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002832
Victor Stinner8c62be82010-05-06 00:08:46 +00002833 errno = 0;
2834 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002835#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00002836 if (value == 0)
2837 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002838#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002839 if (value == -1 && errno != 0)
2840 /* either nice() or getpriority() returned an error */
2841 return posix_error();
2842 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002843}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002844#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002845
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002846PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002847"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002848Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002849
Barry Warsaw53699e91996-12-10 23:23:01 +00002850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002851posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002852{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002853#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002854 PyObject *o1, *o2;
2855 char *p1, *p2;
2856 BOOL result;
2857 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2858 goto error;
2859 if (!convert_to_unicode(&o1))
2860 goto error;
2861 if (!convert_to_unicode(&o2)) {
2862 Py_DECREF(o1);
2863 goto error;
2864 }
2865 Py_BEGIN_ALLOW_THREADS
2866 result = MoveFileW(PyUnicode_AsUnicode(o1),
2867 PyUnicode_AsUnicode(o2));
2868 Py_END_ALLOW_THREADS
2869 Py_DECREF(o1);
2870 Py_DECREF(o2);
2871 if (!result)
2872 return win32_error("rename", NULL);
2873 Py_INCREF(Py_None);
2874 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002875error:
Victor Stinner8c62be82010-05-06 00:08:46 +00002876 PyErr_Clear();
2877 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2878 return NULL;
2879 Py_BEGIN_ALLOW_THREADS
2880 result = MoveFileA(p1, p2);
2881 Py_END_ALLOW_THREADS
2882 if (!result)
2883 return win32_error("rename", NULL);
2884 Py_INCREF(Py_None);
2885 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002886#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002887 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002888#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002889}
2890
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002891
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002892PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002893"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002894Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002895
Barry Warsaw53699e91996-12-10 23:23:01 +00002896static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002897posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002898{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002899#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002900 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002901#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002902 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002903#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002904}
2905
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002906
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002907PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002908"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002909Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002910
Barry Warsaw53699e91996-12-10 23:23:01 +00002911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002912posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002913{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002914#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00002915 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002916#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002917 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002918#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002919}
2920
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002921
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002922#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002923PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002924"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002925Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002926
Barry Warsaw53699e91996-12-10 23:23:01 +00002927static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002928posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002929{
Victor Stinner8c62be82010-05-06 00:08:46 +00002930 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002931#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002932 wchar_t *command;
2933 if (!PyArg_ParseTuple(args, "u:system", &command))
2934 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002935
Victor Stinner8c62be82010-05-06 00:08:46 +00002936 Py_BEGIN_ALLOW_THREADS
2937 sts = _wsystem(command);
2938 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00002939#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002940 PyObject *command_obj;
2941 char *command;
2942 if (!PyArg_ParseTuple(args, "O&:system",
2943 PyUnicode_FSConverter, &command_obj))
2944 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002945
Victor Stinner8c62be82010-05-06 00:08:46 +00002946 command = PyBytes_AsString(command_obj);
2947 Py_BEGIN_ALLOW_THREADS
2948 sts = system(command);
2949 Py_END_ALLOW_THREADS
2950 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00002951#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002952 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002953}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002954#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002955
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002956
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002957PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002958"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002959Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002960
Barry Warsaw53699e91996-12-10 23:23:01 +00002961static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002962posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002963{
Victor Stinner8c62be82010-05-06 00:08:46 +00002964 int i;
2965 if (!PyArg_ParseTuple(args, "i:umask", &i))
2966 return NULL;
2967 i = (int)umask(i);
2968 if (i < 0)
2969 return posix_error();
2970 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002971}
2972
Brian Curtind40e6f72010-07-08 21:39:08 +00002973#ifdef MS_WINDOWS
2974
2975/* override the default DeleteFileW behavior so that directory
2976symlinks can be removed with this function, the same as with
2977Unix symlinks */
2978BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
2979{
2980 WIN32_FILE_ATTRIBUTE_DATA info;
2981 WIN32_FIND_DATAW find_data;
2982 HANDLE find_data_handle;
2983 int is_directory = 0;
2984 int is_link = 0;
2985
2986 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
2987 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
2988
2989 /* Get WIN32_FIND_DATA structure for the path to determine if
2990 it is a symlink */
2991 if(is_directory &&
2992 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
2993 find_data_handle = FindFirstFileW(lpFileName, &find_data);
2994
2995 if(find_data_handle != INVALID_HANDLE_VALUE) {
2996 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
2997 FindClose(find_data_handle);
2998 }
2999 }
3000 }
3001
3002 if (is_directory && is_link)
3003 return RemoveDirectoryW(lpFileName);
3004
3005 return DeleteFileW(lpFileName);
3006}
3007#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003008
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003009PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003010"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003011Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003012
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003013PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003014"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003015Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003016
Barry Warsaw53699e91996-12-10 23:23:01 +00003017static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003018posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003019{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003020#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003021 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3022 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003023#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003024 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003025#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003026}
3027
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003028
Guido van Rossumb6775db1994-08-01 11:34:53 +00003029#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003030PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003031"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003032Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003033
Barry Warsaw53699e91996-12-10 23:23:01 +00003034static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003035posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003036{
Victor Stinner8c62be82010-05-06 00:08:46 +00003037 struct utsname u;
3038 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003039
Victor Stinner8c62be82010-05-06 00:08:46 +00003040 Py_BEGIN_ALLOW_THREADS
3041 res = uname(&u);
3042 Py_END_ALLOW_THREADS
3043 if (res < 0)
3044 return posix_error();
3045 return Py_BuildValue("(sssss)",
3046 u.sysname,
3047 u.nodename,
3048 u.release,
3049 u.version,
3050 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003051}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003052#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003053
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003054static int
3055extract_time(PyObject *t, long* sec, long* usec)
3056{
Victor Stinner8c62be82010-05-06 00:08:46 +00003057 long intval;
3058 if (PyFloat_Check(t)) {
3059 double tval = PyFloat_AsDouble(t);
3060 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
3061 if (!intobj)
3062 return -1;
3063 intval = PyLong_AsLong(intobj);
3064 Py_DECREF(intobj);
3065 if (intval == -1 && PyErr_Occurred())
3066 return -1;
3067 *sec = intval;
3068 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3069 if (*usec < 0)
3070 /* If rounding gave us a negative number,
3071 truncate. */
3072 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003073 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003074 }
3075 intval = PyLong_AsLong(t);
3076 if (intval == -1 && PyErr_Occurred())
3077 return -1;
3078 *sec = intval;
3079 *usec = 0;
3080 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003081}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003082
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003083PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003084"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003085utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003086Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003087second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003088
Barry Warsaw53699e91996-12-10 23:23:01 +00003089static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003090posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003091{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003092#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003093 PyObject *arg;
3094 PyUnicodeObject *obwpath;
3095 wchar_t *wpath = NULL;
3096 PyObject *oapath;
3097 char *apath;
3098 HANDLE hFile;
3099 long atimesec, mtimesec, ausec, musec;
3100 FILETIME atime, mtime;
3101 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003102
Victor Stinner8c62be82010-05-06 00:08:46 +00003103 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3104 wpath = PyUnicode_AS_UNICODE(obwpath);
3105 Py_BEGIN_ALLOW_THREADS
3106 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3107 NULL, OPEN_EXISTING,
3108 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3109 Py_END_ALLOW_THREADS
3110 if (hFile == INVALID_HANDLE_VALUE)
3111 return win32_error_unicode("utime", wpath);
3112 } else
3113 /* Drop the argument parsing error as narrow strings
3114 are also valid. */
3115 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003116
Victor Stinner8c62be82010-05-06 00:08:46 +00003117 if (!wpath) {
3118 if (!PyArg_ParseTuple(args, "O&O:utime",
3119 PyUnicode_FSConverter, &oapath, &arg))
3120 return NULL;
3121 apath = PyBytes_AsString(oapath);
3122 Py_BEGIN_ALLOW_THREADS
3123 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3124 NULL, OPEN_EXISTING,
3125 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3126 Py_END_ALLOW_THREADS
3127 if (hFile == INVALID_HANDLE_VALUE) {
3128 win32_error("utime", apath);
3129 Py_DECREF(oapath);
3130 return NULL;
3131 }
3132 Py_DECREF(oapath);
3133 }
3134
3135 if (arg == Py_None) {
3136 SYSTEMTIME now;
3137 GetSystemTime(&now);
3138 if (!SystemTimeToFileTime(&now, &mtime) ||
3139 !SystemTimeToFileTime(&now, &atime)) {
3140 win32_error("utime", NULL);
3141 goto done;
3142 }
3143 }
3144 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3145 PyErr_SetString(PyExc_TypeError,
3146 "utime() arg 2 must be a tuple (atime, mtime)");
3147 goto done;
3148 }
3149 else {
3150 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3151 &atimesec, &ausec) == -1)
3152 goto done;
3153 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3154 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3155 &mtimesec, &musec) == -1)
3156 goto done;
3157 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3158 }
3159 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3160 /* Avoid putting the file name into the error here,
3161 as that may confuse the user into believing that
3162 something is wrong with the file, when it also
3163 could be the time stamp that gives a problem. */
3164 win32_error("utime", NULL);
3165 }
3166 Py_INCREF(Py_None);
3167 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003168done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003169 CloseHandle(hFile);
3170 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003171#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003172
Victor Stinner8c62be82010-05-06 00:08:46 +00003173 PyObject *opath;
3174 char *path;
3175 long atime, mtime, ausec, musec;
3176 int res;
3177 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003178
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003179#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003180 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003181#define ATIME buf[0].tv_sec
3182#define MTIME buf[1].tv_sec
3183#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003184/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003185 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003186#define ATIME buf.actime
3187#define MTIME buf.modtime
3188#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003189#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003190 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003191#define ATIME buf[0]
3192#define MTIME buf[1]
3193#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003194#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003195
Mark Hammond817c9292003-12-03 01:22:38 +00003196
Victor Stinner8c62be82010-05-06 00:08:46 +00003197 if (!PyArg_ParseTuple(args, "O&O:utime",
3198 PyUnicode_FSConverter, &opath, &arg))
3199 return NULL;
3200 path = PyBytes_AsString(opath);
3201 if (arg == Py_None) {
3202 /* optional time values not given */
3203 Py_BEGIN_ALLOW_THREADS
3204 res = utime(path, NULL);
3205 Py_END_ALLOW_THREADS
3206 }
3207 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3208 PyErr_SetString(PyExc_TypeError,
3209 "utime() arg 2 must be a tuple (atime, mtime)");
3210 Py_DECREF(opath);
3211 return NULL;
3212 }
3213 else {
3214 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3215 &atime, &ausec) == -1) {
3216 Py_DECREF(opath);
3217 return NULL;
3218 }
3219 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3220 &mtime, &musec) == -1) {
3221 Py_DECREF(opath);
3222 return NULL;
3223 }
3224 ATIME = atime;
3225 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003226#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003227 buf[0].tv_usec = ausec;
3228 buf[1].tv_usec = musec;
3229 Py_BEGIN_ALLOW_THREADS
3230 res = utimes(path, buf);
3231 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003232#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003233 Py_BEGIN_ALLOW_THREADS
3234 res = utime(path, UTIME_ARG);
3235 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003236#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003237 }
3238 if (res < 0) {
3239 return posix_error_with_allocated_filename(opath);
3240 }
3241 Py_DECREF(opath);
3242 Py_INCREF(Py_None);
3243 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003244#undef UTIME_ARG
3245#undef ATIME
3246#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003247#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003248}
3249
Guido van Rossum85e3b011991-06-03 12:42:10 +00003250
Guido van Rossum3b066191991-06-04 19:40:25 +00003251/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003252
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003253PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003254"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003255Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003256
Barry Warsaw53699e91996-12-10 23:23:01 +00003257static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003258posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003259{
Victor Stinner8c62be82010-05-06 00:08:46 +00003260 int sts;
3261 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3262 return NULL;
3263 _exit(sts);
3264 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003265}
3266
Martin v. Löwis114619e2002-10-07 06:44:21 +00003267#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3268static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003269free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003270{
Victor Stinner8c62be82010-05-06 00:08:46 +00003271 Py_ssize_t i;
3272 for (i = 0; i < count; i++)
3273 PyMem_Free(array[i]);
3274 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003275}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003276
Antoine Pitrou69f71142009-05-24 21:25:49 +00003277static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003278int fsconvert_strdup(PyObject *o, char**out)
3279{
Victor Stinner8c62be82010-05-06 00:08:46 +00003280 PyObject *bytes;
3281 Py_ssize_t size;
3282 if (!PyUnicode_FSConverter(o, &bytes))
3283 return 0;
3284 size = PyBytes_GET_SIZE(bytes);
3285 *out = PyMem_Malloc(size+1);
3286 if (!*out)
3287 return 0;
3288 memcpy(*out, PyBytes_AsString(bytes), size+1);
3289 Py_DECREF(bytes);
3290 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003291}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003292#endif
3293
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003294
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003295#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003296PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003297"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003298Execute an executable path with arguments, replacing current process.\n\
3299\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003300 path: path of executable file\n\
3301 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003302
Barry Warsaw53699e91996-12-10 23:23:01 +00003303static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003304posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003305{
Victor Stinner8c62be82010-05-06 00:08:46 +00003306 PyObject *opath;
3307 char *path;
3308 PyObject *argv;
3309 char **argvlist;
3310 Py_ssize_t i, argc;
3311 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003312
Victor Stinner8c62be82010-05-06 00:08:46 +00003313 /* execv has two arguments: (path, argv), where
3314 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003315
Victor Stinner8c62be82010-05-06 00:08:46 +00003316 if (!PyArg_ParseTuple(args, "O&O:execv",
3317 PyUnicode_FSConverter,
3318 &opath, &argv))
3319 return NULL;
3320 path = PyBytes_AsString(opath);
3321 if (PyList_Check(argv)) {
3322 argc = PyList_Size(argv);
3323 getitem = PyList_GetItem;
3324 }
3325 else if (PyTuple_Check(argv)) {
3326 argc = PyTuple_Size(argv);
3327 getitem = PyTuple_GetItem;
3328 }
3329 else {
3330 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3331 Py_DECREF(opath);
3332 return NULL;
3333 }
3334 if (argc < 1) {
3335 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3336 Py_DECREF(opath);
3337 return NULL;
3338 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003339
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 argvlist = PyMem_NEW(char *, argc+1);
3341 if (argvlist == NULL) {
3342 Py_DECREF(opath);
3343 return PyErr_NoMemory();
3344 }
3345 for (i = 0; i < argc; i++) {
3346 if (!fsconvert_strdup((*getitem)(argv, i),
3347 &argvlist[i])) {
3348 free_string_array(argvlist, i);
3349 PyErr_SetString(PyExc_TypeError,
3350 "execv() arg 2 must contain only strings");
3351 Py_DECREF(opath);
3352 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003353
Victor Stinner8c62be82010-05-06 00:08:46 +00003354 }
3355 }
3356 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003357
Victor Stinner8c62be82010-05-06 00:08:46 +00003358 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003359
Victor Stinner8c62be82010-05-06 00:08:46 +00003360 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003361
Victor Stinner8c62be82010-05-06 00:08:46 +00003362 free_string_array(argvlist, argc);
3363 Py_DECREF(opath);
3364 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003365}
3366
Victor Stinner13bb71c2010-04-23 21:41:56 +00003367static char**
3368parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3369{
Victor Stinner8c62be82010-05-06 00:08:46 +00003370 char **envlist;
3371 Py_ssize_t i, pos, envc;
3372 PyObject *keys=NULL, *vals=NULL;
3373 PyObject *key, *val, *key2, *val2;
3374 char *p, *k, *v;
3375 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003376
Victor Stinner8c62be82010-05-06 00:08:46 +00003377 i = PyMapping_Size(env);
3378 if (i < 0)
3379 return NULL;
3380 envlist = PyMem_NEW(char *, i + 1);
3381 if (envlist == NULL) {
3382 PyErr_NoMemory();
3383 return NULL;
3384 }
3385 envc = 0;
3386 keys = PyMapping_Keys(env);
3387 vals = PyMapping_Values(env);
3388 if (!keys || !vals)
3389 goto error;
3390 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3391 PyErr_Format(PyExc_TypeError,
3392 "env.keys() or env.values() is not a list");
3393 goto error;
3394 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003395
Victor Stinner8c62be82010-05-06 00:08:46 +00003396 for (pos = 0; pos < i; pos++) {
3397 key = PyList_GetItem(keys, pos);
3398 val = PyList_GetItem(vals, pos);
3399 if (!key || !val)
3400 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003401
Victor Stinner8c62be82010-05-06 00:08:46 +00003402 if (PyUnicode_FSConverter(key, &key2) == 0)
3403 goto error;
3404 if (PyUnicode_FSConverter(val, &val2) == 0) {
3405 Py_DECREF(key2);
3406 goto error;
3407 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003408
3409#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003410 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3411 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003412#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003413 k = PyBytes_AsString(key2);
3414 v = PyBytes_AsString(val2);
3415 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003416
Victor Stinner8c62be82010-05-06 00:08:46 +00003417 p = PyMem_NEW(char, len);
3418 if (p == NULL) {
3419 PyErr_NoMemory();
3420 Py_DECREF(key2);
3421 Py_DECREF(val2);
3422 goto error;
3423 }
3424 PyOS_snprintf(p, len, "%s=%s", k, v);
3425 envlist[envc++] = p;
3426 Py_DECREF(key2);
3427 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003428#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003429 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003430#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003431 }
3432 Py_DECREF(vals);
3433 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003434
Victor Stinner8c62be82010-05-06 00:08:46 +00003435 envlist[envc] = 0;
3436 *envc_ptr = envc;
3437 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003438
3439error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003440 Py_XDECREF(keys);
3441 Py_XDECREF(vals);
3442 while (--envc >= 0)
3443 PyMem_DEL(envlist[envc]);
3444 PyMem_DEL(envlist);
3445 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003446}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003447
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003448PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003449"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003450Execute a path with arguments and environment, replacing current process.\n\
3451\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003452 path: path of executable file\n\
3453 args: tuple or list of arguments\n\
3454 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003455
Barry Warsaw53699e91996-12-10 23:23:01 +00003456static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003457posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003458{
Victor Stinner8c62be82010-05-06 00:08:46 +00003459 PyObject *opath;
3460 char *path;
3461 PyObject *argv, *env;
3462 char **argvlist;
3463 char **envlist;
3464 Py_ssize_t i, argc, envc;
3465 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3466 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003467
Victor Stinner8c62be82010-05-06 00:08:46 +00003468 /* execve has three arguments: (path, argv, env), where
3469 argv is a list or tuple of strings and env is a dictionary
3470 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003471
Victor Stinner8c62be82010-05-06 00:08:46 +00003472 if (!PyArg_ParseTuple(args, "O&OO:execve",
3473 PyUnicode_FSConverter,
3474 &opath, &argv, &env))
3475 return NULL;
3476 path = PyBytes_AsString(opath);
3477 if (PyList_Check(argv)) {
3478 argc = PyList_Size(argv);
3479 getitem = PyList_GetItem;
3480 }
3481 else if (PyTuple_Check(argv)) {
3482 argc = PyTuple_Size(argv);
3483 getitem = PyTuple_GetItem;
3484 }
3485 else {
3486 PyErr_SetString(PyExc_TypeError,
3487 "execve() arg 2 must be a tuple or list");
3488 goto fail_0;
3489 }
3490 if (!PyMapping_Check(env)) {
3491 PyErr_SetString(PyExc_TypeError,
3492 "execve() arg 3 must be a mapping object");
3493 goto fail_0;
3494 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003495
Victor Stinner8c62be82010-05-06 00:08:46 +00003496 argvlist = PyMem_NEW(char *, argc+1);
3497 if (argvlist == NULL) {
3498 PyErr_NoMemory();
3499 goto fail_0;
3500 }
3501 for (i = 0; i < argc; i++) {
3502 if (!fsconvert_strdup((*getitem)(argv, i),
3503 &argvlist[i]))
3504 {
3505 lastarg = i;
3506 goto fail_1;
3507 }
3508 }
3509 lastarg = argc;
3510 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003511
Victor Stinner8c62be82010-05-06 00:08:46 +00003512 envlist = parse_envlist(env, &envc);
3513 if (envlist == NULL)
3514 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003515
Victor Stinner8c62be82010-05-06 00:08:46 +00003516 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003517
Victor Stinner8c62be82010-05-06 00:08:46 +00003518 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003519
Victor Stinner8c62be82010-05-06 00:08:46 +00003520 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003521
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 while (--envc >= 0)
3523 PyMem_DEL(envlist[envc]);
3524 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003525 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003526 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003527 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003528 Py_DECREF(opath);
3529 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003530}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003531#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003532
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003533
Guido van Rossuma1065681999-01-25 23:20:23 +00003534#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003535PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003536"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003537Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003538\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 mode: mode of process creation\n\
3540 path: path of executable file\n\
3541 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003542
3543static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003544posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003545{
Victor Stinner8c62be82010-05-06 00:08:46 +00003546 PyObject *opath;
3547 char *path;
3548 PyObject *argv;
3549 char **argvlist;
3550 int mode, i;
3551 Py_ssize_t argc;
3552 Py_intptr_t spawnval;
3553 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003554
Victor Stinner8c62be82010-05-06 00:08:46 +00003555 /* spawnv has three arguments: (mode, path, argv), where
3556 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003557
Victor Stinner8c62be82010-05-06 00:08:46 +00003558 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3559 PyUnicode_FSConverter,
3560 &opath, &argv))
3561 return NULL;
3562 path = PyBytes_AsString(opath);
3563 if (PyList_Check(argv)) {
3564 argc = PyList_Size(argv);
3565 getitem = PyList_GetItem;
3566 }
3567 else if (PyTuple_Check(argv)) {
3568 argc = PyTuple_Size(argv);
3569 getitem = PyTuple_GetItem;
3570 }
3571 else {
3572 PyErr_SetString(PyExc_TypeError,
3573 "spawnv() arg 2 must be a tuple or list");
3574 Py_DECREF(opath);
3575 return NULL;
3576 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003577
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 argvlist = PyMem_NEW(char *, argc+1);
3579 if (argvlist == NULL) {
3580 Py_DECREF(opath);
3581 return PyErr_NoMemory();
3582 }
3583 for (i = 0; i < argc; i++) {
3584 if (!fsconvert_strdup((*getitem)(argv, i),
3585 &argvlist[i])) {
3586 free_string_array(argvlist, i);
3587 PyErr_SetString(
3588 PyExc_TypeError,
3589 "spawnv() arg 2 must contain only strings");
3590 Py_DECREF(opath);
3591 return NULL;
3592 }
3593 }
3594 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003595
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003596#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003597 Py_BEGIN_ALLOW_THREADS
3598 spawnval = spawnv(mode, path, argvlist);
3599 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003600#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003601 if (mode == _OLD_P_OVERLAY)
3602 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003603
Victor Stinner8c62be82010-05-06 00:08:46 +00003604 Py_BEGIN_ALLOW_THREADS
3605 spawnval = _spawnv(mode, path, argvlist);
3606 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003607#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003608
Victor Stinner8c62be82010-05-06 00:08:46 +00003609 free_string_array(argvlist, argc);
3610 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003611
Victor Stinner8c62be82010-05-06 00:08:46 +00003612 if (spawnval == -1)
3613 return posix_error();
3614 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003615#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003616 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003617#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003618 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003619#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003620}
3621
3622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003623PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003624"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003625Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003626\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003627 mode: mode of process creation\n\
3628 path: path of executable file\n\
3629 args: tuple or list of arguments\n\
3630 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003631
3632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003633posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003634{
Victor Stinner8c62be82010-05-06 00:08:46 +00003635 PyObject *opath;
3636 char *path;
3637 PyObject *argv, *env;
3638 char **argvlist;
3639 char **envlist;
3640 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003641 int mode;
3642 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 Py_intptr_t spawnval;
3644 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3645 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003646
Victor Stinner8c62be82010-05-06 00:08:46 +00003647 /* spawnve has four arguments: (mode, path, argv, env), where
3648 argv is a list or tuple of strings and env is a dictionary
3649 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003650
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3652 PyUnicode_FSConverter,
3653 &opath, &argv, &env))
3654 return NULL;
3655 path = PyBytes_AsString(opath);
3656 if (PyList_Check(argv)) {
3657 argc = PyList_Size(argv);
3658 getitem = PyList_GetItem;
3659 }
3660 else if (PyTuple_Check(argv)) {
3661 argc = PyTuple_Size(argv);
3662 getitem = PyTuple_GetItem;
3663 }
3664 else {
3665 PyErr_SetString(PyExc_TypeError,
3666 "spawnve() arg 2 must be a tuple or list");
3667 goto fail_0;
3668 }
3669 if (!PyMapping_Check(env)) {
3670 PyErr_SetString(PyExc_TypeError,
3671 "spawnve() arg 3 must be a mapping object");
3672 goto fail_0;
3673 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003674
Victor Stinner8c62be82010-05-06 00:08:46 +00003675 argvlist = PyMem_NEW(char *, argc+1);
3676 if (argvlist == NULL) {
3677 PyErr_NoMemory();
3678 goto fail_0;
3679 }
3680 for (i = 0; i < argc; i++) {
3681 if (!fsconvert_strdup((*getitem)(argv, i),
3682 &argvlist[i]))
3683 {
3684 lastarg = i;
3685 goto fail_1;
3686 }
3687 }
3688 lastarg = argc;
3689 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003690
Victor Stinner8c62be82010-05-06 00:08:46 +00003691 envlist = parse_envlist(env, &envc);
3692 if (envlist == NULL)
3693 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003694
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003695#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 Py_BEGIN_ALLOW_THREADS
3697 spawnval = spawnve(mode, path, argvlist, envlist);
3698 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003699#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003700 if (mode == _OLD_P_OVERLAY)
3701 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003702
Victor Stinner8c62be82010-05-06 00:08:46 +00003703 Py_BEGIN_ALLOW_THREADS
3704 spawnval = _spawnve(mode, path, argvlist, envlist);
3705 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003706#endif
Tim Peters25059d32001-12-07 20:35:43 +00003707
Victor Stinner8c62be82010-05-06 00:08:46 +00003708 if (spawnval == -1)
3709 (void) posix_error();
3710 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003711#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003712 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003713#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003714 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003715#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003716
Victor Stinner8c62be82010-05-06 00:08:46 +00003717 while (--envc >= 0)
3718 PyMem_DEL(envlist[envc]);
3719 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003720 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003721 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003722 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003723 Py_DECREF(opath);
3724 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003725}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003726
3727/* OS/2 supports spawnvp & spawnvpe natively */
3728#if defined(PYOS_OS2)
3729PyDoc_STRVAR(posix_spawnvp__doc__,
3730"spawnvp(mode, file, args)\n\n\
3731Execute the program 'file' in a new process, using the environment\n\
3732search path to find the file.\n\
3733\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003734 mode: mode of process creation\n\
3735 file: executable file name\n\
3736 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003737
3738static PyObject *
3739posix_spawnvp(PyObject *self, PyObject *args)
3740{
Victor Stinner8c62be82010-05-06 00:08:46 +00003741 PyObject *opath;
3742 char *path;
3743 PyObject *argv;
3744 char **argvlist;
3745 int mode, i, argc;
3746 Py_intptr_t spawnval;
3747 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003748
Victor Stinner8c62be82010-05-06 00:08:46 +00003749 /* spawnvp has three arguments: (mode, path, argv), where
3750 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003751
Victor Stinner8c62be82010-05-06 00:08:46 +00003752 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3753 PyUnicode_FSConverter,
3754 &opath, &argv))
3755 return NULL;
3756 path = PyBytes_AsString(opath);
3757 if (PyList_Check(argv)) {
3758 argc = PyList_Size(argv);
3759 getitem = PyList_GetItem;
3760 }
3761 else if (PyTuple_Check(argv)) {
3762 argc = PyTuple_Size(argv);
3763 getitem = PyTuple_GetItem;
3764 }
3765 else {
3766 PyErr_SetString(PyExc_TypeError,
3767 "spawnvp() arg 2 must be a tuple or list");
3768 Py_DECREF(opath);
3769 return NULL;
3770 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003771
Victor Stinner8c62be82010-05-06 00:08:46 +00003772 argvlist = PyMem_NEW(char *, argc+1);
3773 if (argvlist == NULL) {
3774 Py_DECREF(opath);
3775 return PyErr_NoMemory();
3776 }
3777 for (i = 0; i < argc; i++) {
3778 if (!fsconvert_strdup((*getitem)(argv, i),
3779 &argvlist[i])) {
3780 free_string_array(argvlist, i);
3781 PyErr_SetString(
3782 PyExc_TypeError,
3783 "spawnvp() arg 2 must contain only strings");
3784 Py_DECREF(opath);
3785 return NULL;
3786 }
3787 }
3788 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003789
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003791#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003792 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003793#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003794 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003795#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003796 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003797
Victor Stinner8c62be82010-05-06 00:08:46 +00003798 free_string_array(argvlist, argc);
3799 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003800
Victor Stinner8c62be82010-05-06 00:08:46 +00003801 if (spawnval == -1)
3802 return posix_error();
3803 else
3804 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003805}
3806
3807
3808PyDoc_STRVAR(posix_spawnvpe__doc__,
3809"spawnvpe(mode, file, args, env)\n\n\
3810Execute the program 'file' in a new process, using the environment\n\
3811search path to find the file.\n\
3812\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003813 mode: mode of process creation\n\
3814 file: executable file name\n\
3815 args: tuple or list of arguments\n\
3816 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003817
3818static PyObject *
3819posix_spawnvpe(PyObject *self, PyObject *args)
3820{
Victor Stinner8c62be82010-05-06 00:08:46 +00003821 PyObject *opath
3822 char *path;
3823 PyObject *argv, *env;
3824 char **argvlist;
3825 char **envlist;
3826 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003827 int mode;
3828 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003829 Py_intptr_t spawnval;
3830 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3831 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003832
Victor Stinner8c62be82010-05-06 00:08:46 +00003833 /* spawnvpe has four arguments: (mode, path, argv, env), where
3834 argv is a list or tuple of strings and env is a dictionary
3835 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003836
Victor Stinner8c62be82010-05-06 00:08:46 +00003837 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3838 PyUnicode_FSConverter,
3839 &opath, &argv, &env))
3840 return NULL;
3841 path = PyBytes_AsString(opath);
3842 if (PyList_Check(argv)) {
3843 argc = PyList_Size(argv);
3844 getitem = PyList_GetItem;
3845 }
3846 else if (PyTuple_Check(argv)) {
3847 argc = PyTuple_Size(argv);
3848 getitem = PyTuple_GetItem;
3849 }
3850 else {
3851 PyErr_SetString(PyExc_TypeError,
3852 "spawnvpe() arg 2 must be a tuple or list");
3853 goto fail_0;
3854 }
3855 if (!PyMapping_Check(env)) {
3856 PyErr_SetString(PyExc_TypeError,
3857 "spawnvpe() arg 3 must be a mapping object");
3858 goto fail_0;
3859 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003860
Victor Stinner8c62be82010-05-06 00:08:46 +00003861 argvlist = PyMem_NEW(char *, argc+1);
3862 if (argvlist == NULL) {
3863 PyErr_NoMemory();
3864 goto fail_0;
3865 }
3866 for (i = 0; i < argc; i++) {
3867 if (!fsconvert_strdup((*getitem)(argv, i),
3868 &argvlist[i]))
3869 {
3870 lastarg = i;
3871 goto fail_1;
3872 }
3873 }
3874 lastarg = argc;
3875 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003876
Victor Stinner8c62be82010-05-06 00:08:46 +00003877 envlist = parse_envlist(env, &envc);
3878 if (envlist == NULL)
3879 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003880
Victor Stinner8c62be82010-05-06 00:08:46 +00003881 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003882#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003883 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003884#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003885 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003886#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003887 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003888
Victor Stinner8c62be82010-05-06 00:08:46 +00003889 if (spawnval == -1)
3890 (void) posix_error();
3891 else
3892 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003893
Victor Stinner8c62be82010-05-06 00:08:46 +00003894 while (--envc >= 0)
3895 PyMem_DEL(envlist[envc]);
3896 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003897 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003898 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003899 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003900 Py_DECREF(opath);
3901 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003902}
3903#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003904#endif /* HAVE_SPAWNV */
3905
3906
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003907#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003908PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003909"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003910Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3911\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003912Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003913
3914static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003915posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003916{
Victor Stinner8c62be82010-05-06 00:08:46 +00003917 pid_t pid;
3918 int result = 0;
3919 _PyImport_AcquireLock();
3920 pid = fork1();
3921 if (pid == 0) {
3922 /* child: this clobbers and resets the import lock. */
3923 PyOS_AfterFork();
3924 } else {
3925 /* parent: release the import lock. */
3926 result = _PyImport_ReleaseLock();
3927 }
3928 if (pid == -1)
3929 return posix_error();
3930 if (result < 0) {
3931 /* Don't clobber the OSError if the fork failed. */
3932 PyErr_SetString(PyExc_RuntimeError,
3933 "not holding the import lock");
3934 return NULL;
3935 }
3936 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003937}
3938#endif
3939
3940
Guido van Rossumad0ee831995-03-01 10:34:45 +00003941#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003942PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003943"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003944Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003945Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003946
Barry Warsaw53699e91996-12-10 23:23:01 +00003947static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003948posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003949{
Victor Stinner8c62be82010-05-06 00:08:46 +00003950 pid_t pid;
3951 int result = 0;
3952 _PyImport_AcquireLock();
3953 pid = fork();
3954 if (pid == 0) {
3955 /* child: this clobbers and resets the import lock. */
3956 PyOS_AfterFork();
3957 } else {
3958 /* parent: release the import lock. */
3959 result = _PyImport_ReleaseLock();
3960 }
3961 if (pid == -1)
3962 return posix_error();
3963 if (result < 0) {
3964 /* Don't clobber the OSError if the fork failed. */
3965 PyErr_SetString(PyExc_RuntimeError,
3966 "not holding the import lock");
3967 return NULL;
3968 }
3969 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003970}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003971#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003972
Neal Norwitzb59798b2003-03-21 01:43:31 +00003973/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003974/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3975#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003976#define DEV_PTY_FILE "/dev/ptc"
3977#define HAVE_DEV_PTMX
3978#else
3979#define DEV_PTY_FILE "/dev/ptmx"
3980#endif
3981
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003982#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003983#ifdef HAVE_PTY_H
3984#include <pty.h>
3985#else
3986#ifdef HAVE_LIBUTIL_H
3987#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00003988#else
3989#ifdef HAVE_UTIL_H
3990#include <util.h>
3991#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003992#endif /* HAVE_LIBUTIL_H */
3993#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003994#ifdef HAVE_STROPTS_H
3995#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003996#endif
3997#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003998
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003999#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004000PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004001"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004002Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004003
4004static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004005posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004006{
Victor Stinner8c62be82010-05-06 00:08:46 +00004007 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004008#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004009 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004010#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004011#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004012 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004013#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00004014 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004015#endif
4016#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004017
Thomas Wouters70c21a12000-07-14 14:28:33 +00004018#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004019 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4020 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004021#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004022 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4023 if (slave_name == NULL)
4024 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004025
Victor Stinner8c62be82010-05-06 00:08:46 +00004026 slave_fd = open(slave_name, O_RDWR);
4027 if (slave_fd < 0)
4028 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004029#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004030 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4031 if (master_fd < 0)
4032 return posix_error();
4033 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4034 /* change permission of slave */
4035 if (grantpt(master_fd) < 0) {
4036 PyOS_setsig(SIGCHLD, sig_saved);
4037 return posix_error();
4038 }
4039 /* unlock slave */
4040 if (unlockpt(master_fd) < 0) {
4041 PyOS_setsig(SIGCHLD, sig_saved);
4042 return posix_error();
4043 }
4044 PyOS_setsig(SIGCHLD, sig_saved);
4045 slave_name = ptsname(master_fd); /* get name of slave */
4046 if (slave_name == NULL)
4047 return posix_error();
4048 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4049 if (slave_fd < 0)
4050 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004051#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004052 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4053 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004054#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004055 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004056#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004057#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004058#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004059
Victor Stinner8c62be82010-05-06 00:08:46 +00004060 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004061
Fred Drake8cef4cf2000-06-28 16:40:38 +00004062}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004063#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004064
4065#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004066PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004067"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004068Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4069Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004070To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004071
4072static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004073posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004074{
Victor Stinner8c62be82010-05-06 00:08:46 +00004075 int master_fd = -1, result = 0;
4076 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004077
Victor Stinner8c62be82010-05-06 00:08:46 +00004078 _PyImport_AcquireLock();
4079 pid = forkpty(&master_fd, NULL, NULL, NULL);
4080 if (pid == 0) {
4081 /* child: this clobbers and resets the import lock. */
4082 PyOS_AfterFork();
4083 } else {
4084 /* parent: release the import lock. */
4085 result = _PyImport_ReleaseLock();
4086 }
4087 if (pid == -1)
4088 return posix_error();
4089 if (result < 0) {
4090 /* Don't clobber the OSError if the fork failed. */
4091 PyErr_SetString(PyExc_RuntimeError,
4092 "not holding the import lock");
4093 return NULL;
4094 }
4095 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004096}
4097#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004098
Guido van Rossumad0ee831995-03-01 10:34:45 +00004099#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004100PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004101"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004102Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004103
Barry Warsaw53699e91996-12-10 23:23:01 +00004104static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004105posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004106{
Victor Stinner8c62be82010-05-06 00:08:46 +00004107 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004108}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004109#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004110
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004111
Guido van Rossumad0ee831995-03-01 10:34:45 +00004112#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004113PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004114"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004115Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004116
Barry Warsaw53699e91996-12-10 23:23:01 +00004117static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004118posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004119{
Victor Stinner8c62be82010-05-06 00:08:46 +00004120 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004121}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004122#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004123
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004124
Guido van Rossumad0ee831995-03-01 10:34:45 +00004125#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004126PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004127"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004128Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004129
Barry Warsaw53699e91996-12-10 23:23:01 +00004130static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004131posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004132{
Victor Stinner8c62be82010-05-06 00:08:46 +00004133 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004134}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004135#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004136
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004137
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004138PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004139"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004140Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004141
Barry Warsaw53699e91996-12-10 23:23:01 +00004142static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004143posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004144{
Victor Stinner8c62be82010-05-06 00:08:46 +00004145 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004146}
4147
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004148
Fred Drakec9680921999-12-13 16:37:25 +00004149#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004150PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004151"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004152Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004153
4154static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004155posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004156{
4157 PyObject *result = NULL;
4158
Fred Drakec9680921999-12-13 16:37:25 +00004159#ifdef NGROUPS_MAX
4160#define MAX_GROUPS NGROUPS_MAX
4161#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004162 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004163#define MAX_GROUPS 64
4164#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004165 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004166
4167 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
4168 * This is a helper variable to store the intermediate result when
4169 * that happens.
4170 *
4171 * To keep the code readable the OSX behaviour is unconditional,
4172 * according to the POSIX spec this should be safe on all unix-y
4173 * systems.
4174 */
4175 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00004176 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004177
Victor Stinner8c62be82010-05-06 00:08:46 +00004178 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004179 if (n < 0) {
4180 if (errno == EINVAL) {
4181 n = getgroups(0, NULL);
4182 if (n == -1) {
4183 return posix_error();
4184 }
4185 if (n == 0) {
4186 /* Avoid malloc(0) */
4187 alt_grouplist = grouplist;
4188 } else {
4189 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4190 if (alt_grouplist == NULL) {
4191 errno = EINVAL;
4192 return posix_error();
4193 }
4194 n = getgroups(n, alt_grouplist);
4195 if (n == -1) {
4196 PyMem_Free(alt_grouplist);
4197 return posix_error();
4198 }
4199 }
4200 } else {
4201 return posix_error();
4202 }
4203 }
4204 result = PyList_New(n);
4205 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004206 int i;
4207 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004208 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00004209 if (o == NULL) {
4210 Py_DECREF(result);
4211 result = NULL;
4212 break;
Fred Drakec9680921999-12-13 16:37:25 +00004213 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004214 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004215 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004216 }
4217
4218 if (alt_grouplist != grouplist) {
4219 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00004220 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004221
Fred Drakec9680921999-12-13 16:37:25 +00004222 return result;
4223}
4224#endif
4225
Antoine Pitroub7572f02009-12-02 20:46:48 +00004226#ifdef HAVE_INITGROUPS
4227PyDoc_STRVAR(posix_initgroups__doc__,
4228"initgroups(username, gid) -> None\n\n\
4229Call the system initgroups() to initialize the group access list with all of\n\
4230the groups of which the specified username is a member, plus the specified\n\
4231group id.");
4232
4233static PyObject *
4234posix_initgroups(PyObject *self, PyObject *args)
4235{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004236 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00004237 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004238 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004239 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004240
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004241 if (!PyArg_ParseTuple(args, "O&l:initgroups",
4242 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00004243 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004244 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004245
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004246 res = initgroups(username, (gid_t) gid);
4247 Py_DECREF(oname);
4248 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00004249 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004250
Victor Stinner8c62be82010-05-06 00:08:46 +00004251 Py_INCREF(Py_None);
4252 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004253}
4254#endif
4255
Martin v. Löwis606edc12002-06-13 21:09:11 +00004256#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004257PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004258"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004259Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004260
4261static PyObject *
4262posix_getpgid(PyObject *self, PyObject *args)
4263{
Victor Stinner8c62be82010-05-06 00:08:46 +00004264 pid_t pid, pgid;
4265 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4266 return NULL;
4267 pgid = getpgid(pid);
4268 if (pgid < 0)
4269 return posix_error();
4270 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004271}
4272#endif /* HAVE_GETPGID */
4273
4274
Guido van Rossumb6775db1994-08-01 11:34:53 +00004275#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004276PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004277"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004278Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004279
Barry Warsaw53699e91996-12-10 23:23:01 +00004280static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004281posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004282{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004283#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004284 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004285#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004286 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004287#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004288}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004289#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004290
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004291
Guido van Rossumb6775db1994-08-01 11:34:53 +00004292#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004293PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004294"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004295Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004296
Barry Warsaw53699e91996-12-10 23:23:01 +00004297static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004298posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004299{
Guido van Rossum64933891994-10-20 21:56:42 +00004300#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004301 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004302#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004303 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004304#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004305 return posix_error();
4306 Py_INCREF(Py_None);
4307 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004308}
4309
Guido van Rossumb6775db1994-08-01 11:34:53 +00004310#endif /* HAVE_SETPGRP */
4311
Guido van Rossumad0ee831995-03-01 10:34:45 +00004312#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004313
4314#ifdef MS_WINDOWS
4315#include <tlhelp32.h>
4316
4317static PyObject*
4318win32_getppid()
4319{
4320 HANDLE snapshot;
4321 pid_t mypid;
4322 PyObject* result = NULL;
4323 BOOL have_record;
4324 PROCESSENTRY32 pe;
4325
4326 mypid = getpid(); /* This function never fails */
4327
4328 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
4329 if (snapshot == INVALID_HANDLE_VALUE)
4330 return PyErr_SetFromWindowsErr(GetLastError());
4331
4332 pe.dwSize = sizeof(pe);
4333 have_record = Process32First(snapshot, &pe);
4334 while (have_record) {
4335 if (mypid == (pid_t)pe.th32ProcessID) {
4336 /* We could cache the ulong value in a static variable. */
4337 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
4338 break;
4339 }
4340
4341 have_record = Process32Next(snapshot, &pe);
4342 }
4343
4344 /* If our loop exits and our pid was not found (result will be NULL)
4345 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
4346 * error anyway, so let's raise it. */
4347 if (!result)
4348 result = PyErr_SetFromWindowsErr(GetLastError());
4349
4350 CloseHandle(snapshot);
4351
4352 return result;
4353}
4354#endif /*MS_WINDOWS*/
4355
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004356PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004357"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004358Return the parent's process id. If the parent process has already exited,\n\
4359Windows machines will still return its id; others systems will return the id\n\
4360of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004361
Barry Warsaw53699e91996-12-10 23:23:01 +00004362static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004363posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004364{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004365#ifdef MS_WINDOWS
4366 return win32_getppid();
4367#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004368 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00004369#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004370}
4371#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004372
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004373
Fred Drake12c6e2d1999-12-14 21:25:03 +00004374#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004375PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004376"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004377Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004378
4379static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004380posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004381{
Victor Stinner8c62be82010-05-06 00:08:46 +00004382 PyObject *result = NULL;
4383 char *name;
4384 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004385
Victor Stinner8c62be82010-05-06 00:08:46 +00004386 errno = 0;
4387 name = getlogin();
4388 if (name == NULL) {
4389 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00004390 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004391 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004392 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00004393 }
4394 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004395 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00004396 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004397
Fred Drake12c6e2d1999-12-14 21:25:03 +00004398 return result;
4399}
4400#endif
4401
Guido van Rossumad0ee831995-03-01 10:34:45 +00004402#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004403PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004404"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004405Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004406
Barry Warsaw53699e91996-12-10 23:23:01 +00004407static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004408posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004409{
Victor Stinner8c62be82010-05-06 00:08:46 +00004410 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004411}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004412#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004413
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004414
Guido van Rossumad0ee831995-03-01 10:34:45 +00004415#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004416PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004417"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004418Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004419
Barry Warsaw53699e91996-12-10 23:23:01 +00004420static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004421posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004422{
Victor Stinner8c62be82010-05-06 00:08:46 +00004423 pid_t pid;
4424 int sig;
4425 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4426 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004427#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004428 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4429 APIRET rc;
4430 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004431 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004432
4433 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4434 APIRET rc;
4435 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004436 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004437
4438 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004439 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004440#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004441 if (kill(pid, sig) == -1)
4442 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004443#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004444 Py_INCREF(Py_None);
4445 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004446}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004447#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004448
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004449#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004450PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004451"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004452Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004453
4454static PyObject *
4455posix_killpg(PyObject *self, PyObject *args)
4456{
Victor Stinner8c62be82010-05-06 00:08:46 +00004457 int sig;
4458 pid_t pgid;
4459 /* XXX some man pages make the `pgid` parameter an int, others
4460 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4461 take the same type. Moreover, pid_t is always at least as wide as
4462 int (else compilation of this module fails), which is safe. */
4463 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4464 return NULL;
4465 if (killpg(pgid, sig) == -1)
4466 return posix_error();
4467 Py_INCREF(Py_None);
4468 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004469}
4470#endif
4471
Brian Curtineb24d742010-04-12 17:16:38 +00004472#ifdef MS_WINDOWS
4473PyDoc_STRVAR(win32_kill__doc__,
4474"kill(pid, sig)\n\n\
4475Kill a process with a signal.");
4476
4477static PyObject *
4478win32_kill(PyObject *self, PyObject *args)
4479{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004480 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004481 DWORD pid, sig, err;
4482 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004483
Victor Stinner8c62be82010-05-06 00:08:46 +00004484 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4485 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004486
Victor Stinner8c62be82010-05-06 00:08:46 +00004487 /* Console processes which share a common console can be sent CTRL+C or
4488 CTRL+BREAK events, provided they handle said events. */
4489 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4490 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4491 err = GetLastError();
4492 PyErr_SetFromWindowsErr(err);
4493 }
4494 else
4495 Py_RETURN_NONE;
4496 }
Brian Curtineb24d742010-04-12 17:16:38 +00004497
Victor Stinner8c62be82010-05-06 00:08:46 +00004498 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4499 attempt to open and terminate the process. */
4500 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4501 if (handle == NULL) {
4502 err = GetLastError();
4503 return PyErr_SetFromWindowsErr(err);
4504 }
Brian Curtineb24d742010-04-12 17:16:38 +00004505
Victor Stinner8c62be82010-05-06 00:08:46 +00004506 if (TerminateProcess(handle, sig) == 0) {
4507 err = GetLastError();
4508 result = PyErr_SetFromWindowsErr(err);
4509 } else {
4510 Py_INCREF(Py_None);
4511 result = Py_None;
4512 }
Brian Curtineb24d742010-04-12 17:16:38 +00004513
Victor Stinner8c62be82010-05-06 00:08:46 +00004514 CloseHandle(handle);
4515 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004516}
4517#endif /* MS_WINDOWS */
4518
Guido van Rossumc0125471996-06-28 18:55:32 +00004519#ifdef HAVE_PLOCK
4520
4521#ifdef HAVE_SYS_LOCK_H
4522#include <sys/lock.h>
4523#endif
4524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004525PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004526"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004527Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004528
Barry Warsaw53699e91996-12-10 23:23:01 +00004529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004530posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004531{
Victor Stinner8c62be82010-05-06 00:08:46 +00004532 int op;
4533 if (!PyArg_ParseTuple(args, "i:plock", &op))
4534 return NULL;
4535 if (plock(op) == -1)
4536 return posix_error();
4537 Py_INCREF(Py_None);
4538 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004539}
4540#endif
4541
Guido van Rossumb6775db1994-08-01 11:34:53 +00004542#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004543PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004544"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004545Set the current process's user id.");
4546
Barry Warsaw53699e91996-12-10 23:23:01 +00004547static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004548posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004549{
Victor Stinner8c62be82010-05-06 00:08:46 +00004550 long uid_arg;
4551 uid_t uid;
4552 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4553 return NULL;
4554 uid = uid_arg;
4555 if (uid != uid_arg) {
4556 PyErr_SetString(PyExc_OverflowError, "user id too big");
4557 return NULL;
4558 }
4559 if (setuid(uid) < 0)
4560 return posix_error();
4561 Py_INCREF(Py_None);
4562 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004563}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004564#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004565
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004566
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004567#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004568PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004569"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004570Set the current process's effective user id.");
4571
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004572static PyObject *
4573posix_seteuid (PyObject *self, PyObject *args)
4574{
Victor Stinner8c62be82010-05-06 00:08:46 +00004575 long euid_arg;
4576 uid_t euid;
4577 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4578 return NULL;
4579 euid = euid_arg;
4580 if (euid != euid_arg) {
4581 PyErr_SetString(PyExc_OverflowError, "user id too big");
4582 return NULL;
4583 }
4584 if (seteuid(euid) < 0) {
4585 return posix_error();
4586 } else {
4587 Py_INCREF(Py_None);
4588 return Py_None;
4589 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004590}
4591#endif /* HAVE_SETEUID */
4592
4593#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004594PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004595"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004596Set the current process's effective group id.");
4597
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004598static PyObject *
4599posix_setegid (PyObject *self, PyObject *args)
4600{
Victor Stinner8c62be82010-05-06 00:08:46 +00004601 long egid_arg;
4602 gid_t egid;
4603 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4604 return NULL;
4605 egid = egid_arg;
4606 if (egid != egid_arg) {
4607 PyErr_SetString(PyExc_OverflowError, "group id too big");
4608 return NULL;
4609 }
4610 if (setegid(egid) < 0) {
4611 return posix_error();
4612 } else {
4613 Py_INCREF(Py_None);
4614 return Py_None;
4615 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004616}
4617#endif /* HAVE_SETEGID */
4618
4619#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004620PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004621"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004622Set the current process's real and effective user ids.");
4623
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004624static PyObject *
4625posix_setreuid (PyObject *self, PyObject *args)
4626{
Victor Stinner8c62be82010-05-06 00:08:46 +00004627 long ruid_arg, euid_arg;
4628 uid_t ruid, euid;
4629 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4630 return NULL;
4631 if (ruid_arg == -1)
4632 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4633 else
4634 ruid = ruid_arg; /* otherwise, assign from our long */
4635 if (euid_arg == -1)
4636 euid = (uid_t)-1;
4637 else
4638 euid = euid_arg;
4639 if ((euid_arg != -1 && euid != euid_arg) ||
4640 (ruid_arg != -1 && ruid != ruid_arg)) {
4641 PyErr_SetString(PyExc_OverflowError, "user id too big");
4642 return NULL;
4643 }
4644 if (setreuid(ruid, euid) < 0) {
4645 return posix_error();
4646 } else {
4647 Py_INCREF(Py_None);
4648 return Py_None;
4649 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004650}
4651#endif /* HAVE_SETREUID */
4652
4653#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004654PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004655"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004656Set the current process's real and effective group ids.");
4657
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004658static PyObject *
4659posix_setregid (PyObject *self, PyObject *args)
4660{
Victor Stinner8c62be82010-05-06 00:08:46 +00004661 long rgid_arg, egid_arg;
4662 gid_t rgid, egid;
4663 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4664 return NULL;
4665 if (rgid_arg == -1)
4666 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4667 else
4668 rgid = rgid_arg; /* otherwise, assign from our long */
4669 if (egid_arg == -1)
4670 egid = (gid_t)-1;
4671 else
4672 egid = egid_arg;
4673 if ((egid_arg != -1 && egid != egid_arg) ||
4674 (rgid_arg != -1 && rgid != rgid_arg)) {
4675 PyErr_SetString(PyExc_OverflowError, "group id too big");
4676 return NULL;
4677 }
4678 if (setregid(rgid, egid) < 0) {
4679 return posix_error();
4680 } else {
4681 Py_INCREF(Py_None);
4682 return Py_None;
4683 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004684}
4685#endif /* HAVE_SETREGID */
4686
Guido van Rossumb6775db1994-08-01 11:34:53 +00004687#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004688PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004689"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004690Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004691
Barry Warsaw53699e91996-12-10 23:23:01 +00004692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004693posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004694{
Victor Stinner8c62be82010-05-06 00:08:46 +00004695 long gid_arg;
4696 gid_t gid;
4697 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4698 return NULL;
4699 gid = gid_arg;
4700 if (gid != gid_arg) {
4701 PyErr_SetString(PyExc_OverflowError, "group id too big");
4702 return NULL;
4703 }
4704 if (setgid(gid) < 0)
4705 return posix_error();
4706 Py_INCREF(Py_None);
4707 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004708}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004709#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004710
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004711#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004712PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004713"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004714Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004715
4716static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004717posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004718{
Victor Stinner8c62be82010-05-06 00:08:46 +00004719 int i, len;
4720 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004721
Victor Stinner8c62be82010-05-06 00:08:46 +00004722 if (!PySequence_Check(groups)) {
4723 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4724 return NULL;
4725 }
4726 len = PySequence_Size(groups);
4727 if (len > MAX_GROUPS) {
4728 PyErr_SetString(PyExc_ValueError, "too many groups");
4729 return NULL;
4730 }
4731 for(i = 0; i < len; i++) {
4732 PyObject *elem;
4733 elem = PySequence_GetItem(groups, i);
4734 if (!elem)
4735 return NULL;
4736 if (!PyLong_Check(elem)) {
4737 PyErr_SetString(PyExc_TypeError,
4738 "groups must be integers");
4739 Py_DECREF(elem);
4740 return NULL;
4741 } else {
4742 unsigned long x = PyLong_AsUnsignedLong(elem);
4743 if (PyErr_Occurred()) {
4744 PyErr_SetString(PyExc_TypeError,
4745 "group id too big");
4746 Py_DECREF(elem);
4747 return NULL;
4748 }
4749 grouplist[i] = x;
4750 /* read back the value to see if it fitted in gid_t */
4751 if (grouplist[i] != x) {
4752 PyErr_SetString(PyExc_TypeError,
4753 "group id too big");
4754 Py_DECREF(elem);
4755 return NULL;
4756 }
4757 }
4758 Py_DECREF(elem);
4759 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004760
Victor Stinner8c62be82010-05-06 00:08:46 +00004761 if (setgroups(len, grouplist) < 0)
4762 return posix_error();
4763 Py_INCREF(Py_None);
4764 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004765}
4766#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004767
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004768#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4769static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004770wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004771{
Victor Stinner8c62be82010-05-06 00:08:46 +00004772 PyObject *result;
4773 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004774
Victor Stinner8c62be82010-05-06 00:08:46 +00004775 if (pid == -1)
4776 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004777
Victor Stinner8c62be82010-05-06 00:08:46 +00004778 if (struct_rusage == NULL) {
4779 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4780 if (m == NULL)
4781 return NULL;
4782 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4783 Py_DECREF(m);
4784 if (struct_rusage == NULL)
4785 return NULL;
4786 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004787
Victor Stinner8c62be82010-05-06 00:08:46 +00004788 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4789 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4790 if (!result)
4791 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004792
4793#ifndef doubletime
4794#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4795#endif
4796
Victor Stinner8c62be82010-05-06 00:08:46 +00004797 PyStructSequence_SET_ITEM(result, 0,
4798 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4799 PyStructSequence_SET_ITEM(result, 1,
4800 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004801#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004802 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4803 SET_INT(result, 2, ru->ru_maxrss);
4804 SET_INT(result, 3, ru->ru_ixrss);
4805 SET_INT(result, 4, ru->ru_idrss);
4806 SET_INT(result, 5, ru->ru_isrss);
4807 SET_INT(result, 6, ru->ru_minflt);
4808 SET_INT(result, 7, ru->ru_majflt);
4809 SET_INT(result, 8, ru->ru_nswap);
4810 SET_INT(result, 9, ru->ru_inblock);
4811 SET_INT(result, 10, ru->ru_oublock);
4812 SET_INT(result, 11, ru->ru_msgsnd);
4813 SET_INT(result, 12, ru->ru_msgrcv);
4814 SET_INT(result, 13, ru->ru_nsignals);
4815 SET_INT(result, 14, ru->ru_nvcsw);
4816 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004817#undef SET_INT
4818
Victor Stinner8c62be82010-05-06 00:08:46 +00004819 if (PyErr_Occurred()) {
4820 Py_DECREF(result);
4821 return NULL;
4822 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004823
Victor Stinner8c62be82010-05-06 00:08:46 +00004824 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004825}
4826#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4827
4828#ifdef HAVE_WAIT3
4829PyDoc_STRVAR(posix_wait3__doc__,
4830"wait3(options) -> (pid, status, rusage)\n\n\
4831Wait for completion of a child process.");
4832
4833static PyObject *
4834posix_wait3(PyObject *self, PyObject *args)
4835{
Victor Stinner8c62be82010-05-06 00:08:46 +00004836 pid_t pid;
4837 int options;
4838 struct rusage ru;
4839 WAIT_TYPE status;
4840 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004841
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4843 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004844
Victor Stinner8c62be82010-05-06 00:08:46 +00004845 Py_BEGIN_ALLOW_THREADS
4846 pid = wait3(&status, options, &ru);
4847 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004848
Victor Stinner8c62be82010-05-06 00:08:46 +00004849 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004850}
4851#endif /* HAVE_WAIT3 */
4852
4853#ifdef HAVE_WAIT4
4854PyDoc_STRVAR(posix_wait4__doc__,
4855"wait4(pid, options) -> (pid, status, rusage)\n\n\
4856Wait for completion of a given child process.");
4857
4858static PyObject *
4859posix_wait4(PyObject *self, PyObject *args)
4860{
Victor Stinner8c62be82010-05-06 00:08:46 +00004861 pid_t pid;
4862 int options;
4863 struct rusage ru;
4864 WAIT_TYPE status;
4865 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004866
Victor Stinner8c62be82010-05-06 00:08:46 +00004867 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
4868 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004869
Victor Stinner8c62be82010-05-06 00:08:46 +00004870 Py_BEGIN_ALLOW_THREADS
4871 pid = wait4(pid, &status, options, &ru);
4872 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004873
Victor Stinner8c62be82010-05-06 00:08:46 +00004874 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004875}
4876#endif /* HAVE_WAIT4 */
4877
Guido van Rossumb6775db1994-08-01 11:34:53 +00004878#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004879PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004880"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004881Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004882
Barry Warsaw53699e91996-12-10 23:23:01 +00004883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004884posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004885{
Victor Stinner8c62be82010-05-06 00:08:46 +00004886 pid_t pid;
4887 int options;
4888 WAIT_TYPE status;
4889 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004890
Victor Stinner8c62be82010-05-06 00:08:46 +00004891 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4892 return NULL;
4893 Py_BEGIN_ALLOW_THREADS
4894 pid = waitpid(pid, &status, options);
4895 Py_END_ALLOW_THREADS
4896 if (pid == -1)
4897 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004898
Victor Stinner8c62be82010-05-06 00:08:46 +00004899 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004900}
4901
Tim Petersab034fa2002-02-01 11:27:43 +00004902#elif defined(HAVE_CWAIT)
4903
4904/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004905PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004906"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004907"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004908
4909static PyObject *
4910posix_waitpid(PyObject *self, PyObject *args)
4911{
Victor Stinner8c62be82010-05-06 00:08:46 +00004912 Py_intptr_t pid;
4913 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004914
Victor Stinner8c62be82010-05-06 00:08:46 +00004915 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4916 return NULL;
4917 Py_BEGIN_ALLOW_THREADS
4918 pid = _cwait(&status, pid, options);
4919 Py_END_ALLOW_THREADS
4920 if (pid == -1)
4921 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004922
Victor Stinner8c62be82010-05-06 00:08:46 +00004923 /* shift the status left a byte so this is more like the POSIX waitpid */
4924 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004925}
4926#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004927
Guido van Rossumad0ee831995-03-01 10:34:45 +00004928#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004929PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004930"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004931Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004932
Barry Warsaw53699e91996-12-10 23:23:01 +00004933static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004934posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004935{
Victor Stinner8c62be82010-05-06 00:08:46 +00004936 pid_t pid;
4937 WAIT_TYPE status;
4938 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004939
Victor Stinner8c62be82010-05-06 00:08:46 +00004940 Py_BEGIN_ALLOW_THREADS
4941 pid = wait(&status);
4942 Py_END_ALLOW_THREADS
4943 if (pid == -1)
4944 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004945
Victor Stinner8c62be82010-05-06 00:08:46 +00004946 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004947}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004948#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004949
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004950
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004951PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004952"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004953Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004954
Barry Warsaw53699e91996-12-10 23:23:01 +00004955static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004956posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004957{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004958#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00004959 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004960#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004961#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00004962 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat",
4963 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004964#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004965 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004966#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004967#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004968}
4969
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004970
Guido van Rossumb6775db1994-08-01 11:34:53 +00004971#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004972PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004973"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004974Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004975
Barry Warsaw53699e91996-12-10 23:23:01 +00004976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004977posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004978{
Victor Stinner8c62be82010-05-06 00:08:46 +00004979 PyObject* v;
4980 char buf[MAXPATHLEN];
4981 PyObject *opath;
4982 char *path;
4983 int n;
4984 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004985
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 if (!PyArg_ParseTuple(args, "O&:readlink",
4987 PyUnicode_FSConverter, &opath))
4988 return NULL;
4989 path = PyBytes_AsString(opath);
4990 v = PySequence_GetItem(args, 0);
4991 if (v == NULL) {
4992 Py_DECREF(opath);
4993 return NULL;
4994 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00004995
Victor Stinner8c62be82010-05-06 00:08:46 +00004996 if (PyUnicode_Check(v)) {
4997 arg_is_unicode = 1;
4998 }
4999 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005000
Victor Stinner8c62be82010-05-06 00:08:46 +00005001 Py_BEGIN_ALLOW_THREADS
5002 n = readlink(path, buf, (int) sizeof buf);
5003 Py_END_ALLOW_THREADS
5004 if (n < 0)
5005 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005006
Victor Stinner8c62be82010-05-06 00:08:46 +00005007 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00005008 if (arg_is_unicode)
5009 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
5010 else
5011 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005012}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005013#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005014
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005015
Guido van Rossumb6775db1994-08-01 11:34:53 +00005016#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005017PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005018"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005019Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005020
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005021static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005022posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005023{
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005025}
5026#endif /* HAVE_SYMLINK */
5027
Brian Curtind40e6f72010-07-08 21:39:08 +00005028#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
5029
5030PyDoc_STRVAR(win_readlink__doc__,
5031"readlink(path) -> path\n\n\
5032Return a string representing the path to which the symbolic link points.");
5033
5034/* The following structure was copied from
5035 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
5036 include doesn't seem to be present in the Windows SDK (at least as included
5037 with Visual Studio Express). */
5038typedef struct _REPARSE_DATA_BUFFER {
5039 ULONG ReparseTag;
5040 USHORT ReparseDataLength;
5041 USHORT Reserved;
5042 union {
5043 struct {
5044 USHORT SubstituteNameOffset;
5045 USHORT SubstituteNameLength;
5046 USHORT PrintNameOffset;
5047 USHORT PrintNameLength;
5048 ULONG Flags;
5049 WCHAR PathBuffer[1];
5050 } SymbolicLinkReparseBuffer;
5051
5052 struct {
5053 USHORT SubstituteNameOffset;
5054 USHORT SubstituteNameLength;
5055 USHORT PrintNameOffset;
5056 USHORT PrintNameLength;
5057 WCHAR PathBuffer[1];
5058 } MountPointReparseBuffer;
5059
5060 struct {
5061 UCHAR DataBuffer[1];
5062 } GenericReparseBuffer;
5063 };
5064} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
5065
Brian Curtin74e45612010-07-09 15:58:59 +00005066#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
5067 GenericReparseBuffer)
Brian Curtind40e6f72010-07-08 21:39:08 +00005068
5069#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
5070
5071/* Windows readlink implementation */
5072static PyObject *
5073win_readlink(PyObject *self, PyObject *args)
5074{
5075 wchar_t *path;
5076 DWORD n_bytes_returned;
5077 DWORD io_result;
5078 PyObject *result;
5079 HANDLE reparse_point_handle;
5080
5081 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
5082 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
5083 wchar_t *print_name;
5084
5085 if (!PyArg_ParseTuple(args,
5086 "u:readlink",
5087 &path))
5088 return NULL;
5089
5090 /* First get a handle to the reparse point */
5091 Py_BEGIN_ALLOW_THREADS
5092 reparse_point_handle = CreateFileW(
5093 path,
5094 0,
5095 0,
5096 0,
5097 OPEN_EXISTING,
5098 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
5099 0);
5100 Py_END_ALLOW_THREADS
5101
5102 if (reparse_point_handle==INVALID_HANDLE_VALUE)
5103 {
5104 return win32_error_unicode("readlink", path);
5105 }
5106
5107 Py_BEGIN_ALLOW_THREADS
5108 /* New call DeviceIoControl to read the reparse point */
5109 io_result = DeviceIoControl(
5110 reparse_point_handle,
5111 FSCTL_GET_REPARSE_POINT,
5112 0, 0, /* in buffer */
5113 target_buffer, sizeof(target_buffer),
5114 &n_bytes_returned,
5115 0 /* we're not using OVERLAPPED_IO */
5116 );
5117 CloseHandle(reparse_point_handle);
5118 Py_END_ALLOW_THREADS
5119
5120 if (io_result==0)
5121 {
5122 return win32_error_unicode("readlink", path);
5123 }
5124
5125 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5126 {
5127 PyErr_SetString(PyExc_ValueError,
5128 "not a symbolic link");
5129 return NULL;
5130 }
Brian Curtin74e45612010-07-09 15:58:59 +00005131 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
5132 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5133
5134 result = PyUnicode_FromWideChar(print_name,
5135 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00005136 return result;
5137}
5138
5139#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5140
5141#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
5142
5143/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5144static int has_CreateSymbolicLinkW = 0;
5145static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5146static int
5147check_CreateSymbolicLinkW()
5148{
5149 HINSTANCE hKernel32;
5150 /* only recheck */
5151 if (has_CreateSymbolicLinkW)
5152 return has_CreateSymbolicLinkW;
5153 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00005154 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
5155 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00005156 if (Py_CreateSymbolicLinkW)
5157 has_CreateSymbolicLinkW = 1;
5158 return has_CreateSymbolicLinkW;
5159}
5160
5161PyDoc_STRVAR(win_symlink__doc__,
5162"symlink(src, dst, target_is_directory=False)\n\n\
5163Create a symbolic link pointing to src named dst.\n\
5164target_is_directory is required if the target is to be interpreted as\n\
5165a directory.\n\
5166This function requires Windows 6.0 or greater, and raises a\n\
5167NotImplementedError otherwise.");
5168
5169static PyObject *
5170win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5171{
5172 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5173 PyObject *src, *dest;
5174 int target_is_directory = 0;
5175 DWORD res;
5176 WIN32_FILE_ATTRIBUTE_DATA src_info;
5177
5178 if (!check_CreateSymbolicLinkW())
5179 {
5180 /* raise NotImplementedError */
5181 return PyErr_Format(PyExc_NotImplementedError,
5182 "CreateSymbolicLinkW not found");
5183 }
5184 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5185 kwlist, &src, &dest, &target_is_directory))
5186 return NULL;
5187 if (!convert_to_unicode(&src)) { return NULL; }
5188 if (!convert_to_unicode(&dest)) {
5189 Py_DECREF(src);
5190 return NULL;
5191 }
5192
5193 /* if src is a directory, ensure target_is_directory==1 */
5194 if(
5195 GetFileAttributesExW(
5196 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5197 ))
5198 {
5199 target_is_directory = target_is_directory ||
5200 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5201 }
5202
5203 Py_BEGIN_ALLOW_THREADS
5204 res = Py_CreateSymbolicLinkW(
5205 PyUnicode_AsUnicode(dest),
5206 PyUnicode_AsUnicode(src),
5207 target_is_directory);
5208 Py_END_ALLOW_THREADS
5209 Py_DECREF(src);
5210 Py_DECREF(dest);
5211 if (!res)
5212 {
5213 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5214 }
5215
5216 Py_INCREF(Py_None);
5217 return Py_None;
5218}
5219#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005220
5221#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005222#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5223static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005224system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005225{
5226 ULONG value = 0;
5227
5228 Py_BEGIN_ALLOW_THREADS
5229 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5230 Py_END_ALLOW_THREADS
5231
5232 return value;
5233}
5234
5235static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005236posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005237{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005238 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005239 return Py_BuildValue("ddddd",
5240 (double)0 /* t.tms_utime / HZ */,
5241 (double)0 /* t.tms_stime / HZ */,
5242 (double)0 /* t.tms_cutime / HZ */,
5243 (double)0 /* t.tms_cstime / HZ */,
5244 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005245}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005246#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005247#define NEED_TICKS_PER_SECOND
5248static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005249static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005250posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005251{
Victor Stinner8c62be82010-05-06 00:08:46 +00005252 struct tms t;
5253 clock_t c;
5254 errno = 0;
5255 c = times(&t);
5256 if (c == (clock_t) -1)
5257 return posix_error();
5258 return Py_BuildValue("ddddd",
5259 (double)t.tms_utime / ticks_per_second,
5260 (double)t.tms_stime / ticks_per_second,
5261 (double)t.tms_cutime / ticks_per_second,
5262 (double)t.tms_cstime / ticks_per_second,
5263 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005264}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005265#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005266#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005267
5268
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005269#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005270#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005271static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005272posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005273{
Victor Stinner8c62be82010-05-06 00:08:46 +00005274 FILETIME create, exit, kernel, user;
5275 HANDLE hProc;
5276 hProc = GetCurrentProcess();
5277 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5278 /* The fields of a FILETIME structure are the hi and lo part
5279 of a 64-bit value expressed in 100 nanosecond units.
5280 1e7 is one second in such units; 1e-7 the inverse.
5281 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5282 */
5283 return Py_BuildValue(
5284 "ddddd",
5285 (double)(user.dwHighDateTime*429.4967296 +
5286 user.dwLowDateTime*1e-7),
5287 (double)(kernel.dwHighDateTime*429.4967296 +
5288 kernel.dwLowDateTime*1e-7),
5289 (double)0,
5290 (double)0,
5291 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005292}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005293#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005294
5295#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005296PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005297"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005298Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005299#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005301
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005302#ifdef HAVE_GETSID
5303PyDoc_STRVAR(posix_getsid__doc__,
5304"getsid(pid) -> sid\n\n\
5305Call the system call getsid().");
5306
5307static PyObject *
5308posix_getsid(PyObject *self, PyObject *args)
5309{
Victor Stinner8c62be82010-05-06 00:08:46 +00005310 pid_t pid;
5311 int sid;
5312 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5313 return NULL;
5314 sid = getsid(pid);
5315 if (sid < 0)
5316 return posix_error();
5317 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005318}
5319#endif /* HAVE_GETSID */
5320
5321
Guido van Rossumb6775db1994-08-01 11:34:53 +00005322#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005323PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005324"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005325Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005326
Barry Warsaw53699e91996-12-10 23:23:01 +00005327static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005328posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005329{
Victor Stinner8c62be82010-05-06 00:08:46 +00005330 if (setsid() < 0)
5331 return posix_error();
5332 Py_INCREF(Py_None);
5333 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005334}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005335#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005336
Guido van Rossumb6775db1994-08-01 11:34:53 +00005337#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005338PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005339"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005340Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005341
Barry Warsaw53699e91996-12-10 23:23:01 +00005342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005343posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005344{
Victor Stinner8c62be82010-05-06 00:08:46 +00005345 pid_t pid;
5346 int pgrp;
5347 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5348 return NULL;
5349 if (setpgid(pid, pgrp) < 0)
5350 return posix_error();
5351 Py_INCREF(Py_None);
5352 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005353}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005354#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005356
Guido van Rossumb6775db1994-08-01 11:34:53 +00005357#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005358PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005359"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005360Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005361
Barry Warsaw53699e91996-12-10 23:23:01 +00005362static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005363posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005364{
Victor Stinner8c62be82010-05-06 00:08:46 +00005365 int fd;
5366 pid_t pgid;
5367 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5368 return NULL;
5369 pgid = tcgetpgrp(fd);
5370 if (pgid < 0)
5371 return posix_error();
5372 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005373}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005374#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005375
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005376
Guido van Rossumb6775db1994-08-01 11:34:53 +00005377#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005378PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005379"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005380Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005381
Barry Warsaw53699e91996-12-10 23:23:01 +00005382static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005383posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005384{
Victor Stinner8c62be82010-05-06 00:08:46 +00005385 int fd;
5386 pid_t pgid;
5387 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5388 return NULL;
5389 if (tcsetpgrp(fd, pgid) < 0)
5390 return posix_error();
5391 Py_INCREF(Py_None);
5392 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005393}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005394#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005395
Guido van Rossum687dd131993-05-17 08:34:16 +00005396/* Functions acting on file descriptors */
5397
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005398PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005399"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005400Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005401
Barry Warsaw53699e91996-12-10 23:23:01 +00005402static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005403posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005404{
Victor Stinner8c62be82010-05-06 00:08:46 +00005405 PyObject *ofile;
5406 char *file;
5407 int flag;
5408 int mode = 0777;
5409 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005410
5411#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005412 PyUnicodeObject *po;
5413 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5414 Py_BEGIN_ALLOW_THREADS
5415 /* PyUnicode_AS_UNICODE OK without thread
5416 lock as it is a simple dereference. */
5417 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5418 Py_END_ALLOW_THREADS
5419 if (fd < 0)
5420 return posix_error();
5421 return PyLong_FromLong((long)fd);
5422 }
5423 /* Drop the argument parsing error as narrow strings
5424 are also valid. */
5425 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005426#endif
5427
Victor Stinner8c62be82010-05-06 00:08:46 +00005428 if (!PyArg_ParseTuple(args, "O&i|i",
5429 PyUnicode_FSConverter, &ofile,
5430 &flag, &mode))
5431 return NULL;
5432 file = PyBytes_AsString(ofile);
5433 Py_BEGIN_ALLOW_THREADS
5434 fd = open(file, flag, mode);
5435 Py_END_ALLOW_THREADS
5436 if (fd < 0)
5437 return posix_error_with_allocated_filename(ofile);
5438 Py_DECREF(ofile);
5439 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005440}
5441
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005442
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005443PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005444"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005445Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005446
Barry Warsaw53699e91996-12-10 23:23:01 +00005447static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005448posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005449{
Victor Stinner8c62be82010-05-06 00:08:46 +00005450 int fd, res;
5451 if (!PyArg_ParseTuple(args, "i:close", &fd))
5452 return NULL;
5453 if (!_PyVerify_fd(fd))
5454 return posix_error();
5455 Py_BEGIN_ALLOW_THREADS
5456 res = close(fd);
5457 Py_END_ALLOW_THREADS
5458 if (res < 0)
5459 return posix_error();
5460 Py_INCREF(Py_None);
5461 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005462}
5463
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005464
Victor Stinner8c62be82010-05-06 00:08:46 +00005465PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005466"closerange(fd_low, fd_high)\n\n\
5467Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5468
5469static PyObject *
5470posix_closerange(PyObject *self, PyObject *args)
5471{
Victor Stinner8c62be82010-05-06 00:08:46 +00005472 int fd_from, fd_to, i;
5473 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5474 return NULL;
5475 Py_BEGIN_ALLOW_THREADS
5476 for (i = fd_from; i < fd_to; i++)
5477 if (_PyVerify_fd(i))
5478 close(i);
5479 Py_END_ALLOW_THREADS
5480 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005481}
5482
5483
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005484PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005485"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005486Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005487
Barry Warsaw53699e91996-12-10 23:23:01 +00005488static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005489posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005490{
Victor Stinner8c62be82010-05-06 00:08:46 +00005491 int fd;
5492 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5493 return NULL;
5494 if (!_PyVerify_fd(fd))
5495 return posix_error();
5496 Py_BEGIN_ALLOW_THREADS
5497 fd = dup(fd);
5498 Py_END_ALLOW_THREADS
5499 if (fd < 0)
5500 return posix_error();
5501 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005502}
5503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005504
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005505PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005506"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005507Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005508
Barry Warsaw53699e91996-12-10 23:23:01 +00005509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005510posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005511{
Victor Stinner8c62be82010-05-06 00:08:46 +00005512 int fd, fd2, res;
5513 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5514 return NULL;
5515 if (!_PyVerify_fd_dup2(fd, fd2))
5516 return posix_error();
5517 Py_BEGIN_ALLOW_THREADS
5518 res = dup2(fd, fd2);
5519 Py_END_ALLOW_THREADS
5520 if (res < 0)
5521 return posix_error();
5522 Py_INCREF(Py_None);
5523 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005524}
5525
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005526
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005527PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005528"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005529Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005530
Barry Warsaw53699e91996-12-10 23:23:01 +00005531static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005532posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005533{
Victor Stinner8c62be82010-05-06 00:08:46 +00005534 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005535#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005536 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005537#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005538 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005539#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005540 PyObject *posobj;
5541 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5542 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005543#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005544 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5545 switch (how) {
5546 case 0: how = SEEK_SET; break;
5547 case 1: how = SEEK_CUR; break;
5548 case 2: how = SEEK_END; break;
5549 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005550#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005551
5552#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005553 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005554#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005555 pos = PyLong_Check(posobj) ?
5556 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005557#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005558 if (PyErr_Occurred())
5559 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005560
Victor Stinner8c62be82010-05-06 00:08:46 +00005561 if (!_PyVerify_fd(fd))
5562 return posix_error();
5563 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005564#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005565 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005566#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005567 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005568#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005569 Py_END_ALLOW_THREADS
5570 if (res < 0)
5571 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005572
5573#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005574 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005575#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005576 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005577#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005578}
5579
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005580
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005581PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005582"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005583Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005584
Barry Warsaw53699e91996-12-10 23:23:01 +00005585static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005586posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005587{
Victor Stinner8c62be82010-05-06 00:08:46 +00005588 int fd, size;
5589 Py_ssize_t n;
5590 PyObject *buffer;
5591 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5592 return NULL;
5593 if (size < 0) {
5594 errno = EINVAL;
5595 return posix_error();
5596 }
5597 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5598 if (buffer == NULL)
5599 return NULL;
5600 if (!_PyVerify_fd(fd))
5601 return posix_error();
5602 Py_BEGIN_ALLOW_THREADS
5603 n = read(fd, PyBytes_AS_STRING(buffer), size);
5604 Py_END_ALLOW_THREADS
5605 if (n < 0) {
5606 Py_DECREF(buffer);
5607 return posix_error();
5608 }
5609 if (n != size)
5610 _PyBytes_Resize(&buffer, n);
5611 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005612}
5613
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005614
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005615PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005616"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005617Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005618
Barry Warsaw53699e91996-12-10 23:23:01 +00005619static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005620posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005621{
Victor Stinner8c62be82010-05-06 00:08:46 +00005622 Py_buffer pbuf;
5623 int fd;
5624 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005625
Victor Stinner8c62be82010-05-06 00:08:46 +00005626 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5627 return NULL;
5628 if (!_PyVerify_fd(fd))
5629 return posix_error();
5630 Py_BEGIN_ALLOW_THREADS
5631 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5632 Py_END_ALLOW_THREADS
5633 PyBuffer_Release(&pbuf);
5634 if (size < 0)
5635 return posix_error();
5636 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005637}
5638
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005639
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005640PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005641"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005642Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005643
Barry Warsaw53699e91996-12-10 23:23:01 +00005644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005645posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005646{
Victor Stinner8c62be82010-05-06 00:08:46 +00005647 int fd;
5648 STRUCT_STAT st;
5649 int res;
5650 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5651 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005652#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005653 /* on OpenVMS we must ensure that all bytes are written to the file */
5654 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005655#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005656 if (!_PyVerify_fd(fd))
5657 return posix_error();
5658 Py_BEGIN_ALLOW_THREADS
5659 res = FSTAT(fd, &st);
5660 Py_END_ALLOW_THREADS
5661 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005662#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005663 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005664#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005665 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005666#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005667 }
Tim Peters5aa91602002-01-30 05:46:57 +00005668
Victor Stinner8c62be82010-05-06 00:08:46 +00005669 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005670}
5671
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005672PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005673"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005674Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005675connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005676
5677static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005678posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005679{
Victor Stinner8c62be82010-05-06 00:08:46 +00005680 int fd;
5681 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5682 return NULL;
5683 if (!_PyVerify_fd(fd))
5684 return PyBool_FromLong(0);
5685 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005686}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005687
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005688#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005689PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005690"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005691Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005692
Barry Warsaw53699e91996-12-10 23:23:01 +00005693static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005694posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005695{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005696#if defined(PYOS_OS2)
5697 HFILE read, write;
5698 APIRET rc;
5699
Victor Stinner8c62be82010-05-06 00:08:46 +00005700 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005701 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005702 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005703 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005704 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005705
5706 return Py_BuildValue("(ii)", read, write);
5707#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005708#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005709 int fds[2];
5710 int res;
5711 Py_BEGIN_ALLOW_THREADS
5712 res = pipe(fds);
5713 Py_END_ALLOW_THREADS
5714 if (res != 0)
5715 return posix_error();
5716 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005717#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00005718 HANDLE read, write;
5719 int read_fd, write_fd;
5720 BOOL ok;
5721 Py_BEGIN_ALLOW_THREADS
5722 ok = CreatePipe(&read, &write, NULL, 0);
5723 Py_END_ALLOW_THREADS
5724 if (!ok)
5725 return win32_error("CreatePipe", NULL);
5726 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5727 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5728 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005729#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005730#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005731}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005732#endif /* HAVE_PIPE */
5733
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005734
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005735#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005736PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005737"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005738Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005739
Barry Warsaw53699e91996-12-10 23:23:01 +00005740static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005741posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005742{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005743 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005744 char *filename;
5745 int mode = 0666;
5746 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005747 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5748 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00005749 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005750 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005751 Py_BEGIN_ALLOW_THREADS
5752 res = mkfifo(filename, mode);
5753 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005754 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005755 if (res < 0)
5756 return posix_error();
5757 Py_INCREF(Py_None);
5758 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005759}
5760#endif
5761
5762
Neal Norwitz11690112002-07-30 01:08:28 +00005763#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005764PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005765"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005766Create a filesystem node (file, device special file or named pipe)\n\
5767named filename. mode specifies both the permissions to use and the\n\
5768type of node to be created, being combined (bitwise OR) with one of\n\
5769S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005770device defines the newly created device special file (probably using\n\
5771os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005772
5773
5774static PyObject *
5775posix_mknod(PyObject *self, PyObject *args)
5776{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005777 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005778 char *filename;
5779 int mode = 0600;
5780 int device = 0;
5781 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005782 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5783 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00005784 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005785 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005786 Py_BEGIN_ALLOW_THREADS
5787 res = mknod(filename, mode, device);
5788 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005789 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005790 if (res < 0)
5791 return posix_error();
5792 Py_INCREF(Py_None);
5793 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005794}
5795#endif
5796
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005797#ifdef HAVE_DEVICE_MACROS
5798PyDoc_STRVAR(posix_major__doc__,
5799"major(device) -> major number\n\
5800Extracts a device major number from a raw device number.");
5801
5802static PyObject *
5803posix_major(PyObject *self, PyObject *args)
5804{
Victor Stinner8c62be82010-05-06 00:08:46 +00005805 int device;
5806 if (!PyArg_ParseTuple(args, "i:major", &device))
5807 return NULL;
5808 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005809}
5810
5811PyDoc_STRVAR(posix_minor__doc__,
5812"minor(device) -> minor number\n\
5813Extracts a device minor number from a raw device number.");
5814
5815static PyObject *
5816posix_minor(PyObject *self, PyObject *args)
5817{
Victor Stinner8c62be82010-05-06 00:08:46 +00005818 int device;
5819 if (!PyArg_ParseTuple(args, "i:minor", &device))
5820 return NULL;
5821 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005822}
5823
5824PyDoc_STRVAR(posix_makedev__doc__,
5825"makedev(major, minor) -> device number\n\
5826Composes a raw device number from the major and minor device numbers.");
5827
5828static PyObject *
5829posix_makedev(PyObject *self, PyObject *args)
5830{
Victor Stinner8c62be82010-05-06 00:08:46 +00005831 int major, minor;
5832 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5833 return NULL;
5834 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005835}
5836#endif /* device macros */
5837
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005838
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005839#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005840PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005841"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005842Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005843
Barry Warsaw53699e91996-12-10 23:23:01 +00005844static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005845posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005846{
Victor Stinner8c62be82010-05-06 00:08:46 +00005847 int fd;
5848 off_t length;
5849 int res;
5850 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005851
Victor Stinner8c62be82010-05-06 00:08:46 +00005852 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5853 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005854
5855#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005856 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005857#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005858 length = PyLong_Check(lenobj) ?
5859 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005860#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005861 if (PyErr_Occurred())
5862 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005863
Victor Stinner8c62be82010-05-06 00:08:46 +00005864 Py_BEGIN_ALLOW_THREADS
5865 res = ftruncate(fd, length);
5866 Py_END_ALLOW_THREADS
5867 if (res < 0)
5868 return posix_error();
5869 Py_INCREF(Py_None);
5870 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005871}
5872#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005873
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005874#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005875PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005876"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005877Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005878
Fred Drake762e2061999-08-26 17:23:54 +00005879/* Save putenv() parameters as values here, so we can collect them when they
5880 * get re-set with another call for the same key. */
5881static PyObject *posix_putenv_garbage;
5882
Tim Peters5aa91602002-01-30 05:46:57 +00005883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005884posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005885{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005886#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005887 wchar_t *s1, *s2;
5888 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005889#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005890 PyObject *os1, *os2;
5891 char *s1, *s2;
5892 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005893#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005894 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005895 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005896
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005897#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005898 if (!PyArg_ParseTuple(args,
5899 "uu:putenv",
5900 &s1, &s2))
5901 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005902#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005903 if (!PyArg_ParseTuple(args,
5904 "O&O&:putenv",
5905 PyUnicode_FSConverter, &os1,
5906 PyUnicode_FSConverter, &os2))
5907 return NULL;
5908 s1 = PyBytes_AsString(os1);
5909 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005910#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005911
5912#if defined(PYOS_OS2)
5913 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5914 APIRET rc;
5915
Guido van Rossumd48f2521997-12-05 22:19:34 +00005916 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005917 if (rc != NO_ERROR) {
5918 os2_error(rc);
5919 goto error;
5920 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005921
5922 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5923 APIRET rc;
5924
Guido van Rossumd48f2521997-12-05 22:19:34 +00005925 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005926 if (rc != NO_ERROR) {
5927 os2_error(rc);
5928 goto error;
5929 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005930 } else {
5931#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005932 /* XXX This can leak memory -- not easy to fix :-( */
5933 /* len includes space for a trailing \0; the size arg to
5934 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005935#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005936 len = wcslen(s1) + wcslen(s2) + 2;
5937 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005938#else
Victor Stinner84ae1182010-05-06 22:05:07 +00005939 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00005940 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005941#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005942 if (newstr == NULL) {
5943 PyErr_NoMemory();
5944 goto error;
5945 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005946#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005947 newenv = PyUnicode_AsUnicode(newstr);
5948 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5949 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005950 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005951 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005952 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005953#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005954 newenv = PyBytes_AS_STRING(newstr);
5955 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5956 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005957 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005958 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005959 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005960#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005961
Victor Stinner8c62be82010-05-06 00:08:46 +00005962 /* Install the first arg and newstr in posix_putenv_garbage;
5963 * this will cause previous value to be collected. This has to
5964 * happen after the real putenv() call because the old value
5965 * was still accessible until then. */
5966 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00005967#ifdef MS_WINDOWS
5968 PyTuple_GET_ITEM(args, 0),
5969#else
5970 os1,
5971#endif
5972 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005973 /* really not much we can do; just leak */
5974 PyErr_Clear();
5975 }
5976 else {
5977 Py_DECREF(newstr);
5978 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005979
5980#if defined(PYOS_OS2)
5981 }
5982#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005983
Martin v. Löwis011e8422009-05-05 04:43:17 +00005984#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005985 Py_DECREF(os1);
5986 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005987#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005988 Py_RETURN_NONE;
5989
5990error:
5991#ifndef MS_WINDOWS
5992 Py_DECREF(os1);
5993 Py_DECREF(os2);
5994#endif
5995 Py_XDECREF(newstr);
5996 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005997}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005998#endif /* putenv */
5999
Guido van Rossumc524d952001-10-19 01:31:59 +00006000#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006001PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006002"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006003Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006004
6005static PyObject *
6006posix_unsetenv(PyObject *self, PyObject *args)
6007{
Victor Stinner84ae1182010-05-06 22:05:07 +00006008#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006009 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006010
Victor Stinner8c62be82010-05-06 00:08:46 +00006011 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6012 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00006013#else
6014 PyObject *os1;
6015 char *s1;
6016
6017 if (!PyArg_ParseTuple(args, "O&:unsetenv",
6018 PyUnicode_FSConverter, &os1))
6019 return NULL;
6020 s1 = PyBytes_AsString(os1);
6021#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006022
Victor Stinner8c62be82010-05-06 00:08:46 +00006023 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006024
Victor Stinner8c62be82010-05-06 00:08:46 +00006025 /* Remove the key from posix_putenv_garbage;
6026 * this will cause it to be collected. This has to
6027 * happen after the real unsetenv() call because the
6028 * old value was still accessible until then.
6029 */
6030 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006031#ifdef MS_WINDOWS
6032 PyTuple_GET_ITEM(args, 0)
6033#else
6034 os1
6035#endif
6036 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006037 /* really not much we can do; just leak */
6038 PyErr_Clear();
6039 }
Guido van Rossumc524d952001-10-19 01:31:59 +00006040
Victor Stinner84ae1182010-05-06 22:05:07 +00006041#ifndef MS_WINDOWS
6042 Py_DECREF(os1);
6043#endif
6044 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00006045}
6046#endif /* unsetenv */
6047
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006048PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006049"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006050Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006051
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006052static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006053posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006054{
Victor Stinner8c62be82010-05-06 00:08:46 +00006055 int code;
6056 char *message;
6057 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6058 return NULL;
6059 message = strerror(code);
6060 if (message == NULL) {
6061 PyErr_SetString(PyExc_ValueError,
6062 "strerror() argument out of range");
6063 return NULL;
6064 }
6065 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006066}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006067
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006068
Guido van Rossumc9641791998-08-04 15:26:23 +00006069#ifdef HAVE_SYS_WAIT_H
6070
Fred Drake106c1a02002-04-23 15:58:02 +00006071#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006072PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006073"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006074Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006075
6076static PyObject *
6077posix_WCOREDUMP(PyObject *self, PyObject *args)
6078{
Victor Stinner8c62be82010-05-06 00:08:46 +00006079 WAIT_TYPE status;
6080 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006081
Victor Stinner8c62be82010-05-06 00:08:46 +00006082 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6083 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006084
Victor Stinner8c62be82010-05-06 00:08:46 +00006085 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006086}
6087#endif /* WCOREDUMP */
6088
6089#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006090PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006091"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006092Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006093job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006094
6095static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006096posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006097{
Victor Stinner8c62be82010-05-06 00:08:46 +00006098 WAIT_TYPE status;
6099 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006100
Victor Stinner8c62be82010-05-06 00:08:46 +00006101 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6102 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006103
Victor Stinner8c62be82010-05-06 00:08:46 +00006104 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006105}
6106#endif /* WIFCONTINUED */
6107
Guido van Rossumc9641791998-08-04 15:26:23 +00006108#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006109PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006110"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006111Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006112
6113static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006114posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006115{
Victor Stinner8c62be82010-05-06 00:08:46 +00006116 WAIT_TYPE status;
6117 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006118
Victor Stinner8c62be82010-05-06 00:08:46 +00006119 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6120 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006121
Victor Stinner8c62be82010-05-06 00:08:46 +00006122 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006123}
6124#endif /* WIFSTOPPED */
6125
6126#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006127PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006128"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006129Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006130
6131static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006132posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006133{
Victor Stinner8c62be82010-05-06 00:08:46 +00006134 WAIT_TYPE status;
6135 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006136
Victor Stinner8c62be82010-05-06 00:08:46 +00006137 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6138 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006139
Victor Stinner8c62be82010-05-06 00:08:46 +00006140 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006141}
6142#endif /* WIFSIGNALED */
6143
6144#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006145PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006146"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006147Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006148system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006149
6150static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006151posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006152{
Victor Stinner8c62be82010-05-06 00:08:46 +00006153 WAIT_TYPE status;
6154 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006155
Victor Stinner8c62be82010-05-06 00:08:46 +00006156 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6157 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006158
Victor Stinner8c62be82010-05-06 00:08:46 +00006159 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006160}
6161#endif /* WIFEXITED */
6162
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006163#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006164PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006165"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006166Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006167
6168static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006169posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006170{
Victor Stinner8c62be82010-05-06 00:08:46 +00006171 WAIT_TYPE status;
6172 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006173
Victor Stinner8c62be82010-05-06 00:08:46 +00006174 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6175 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006176
Victor Stinner8c62be82010-05-06 00:08:46 +00006177 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006178}
6179#endif /* WEXITSTATUS */
6180
6181#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006182PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006183"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006184Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006185value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006186
6187static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006188posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006189{
Victor Stinner8c62be82010-05-06 00:08:46 +00006190 WAIT_TYPE status;
6191 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006192
Victor Stinner8c62be82010-05-06 00:08:46 +00006193 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6194 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006195
Victor Stinner8c62be82010-05-06 00:08:46 +00006196 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006197}
6198#endif /* WTERMSIG */
6199
6200#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006201PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006202"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006203Return the signal that stopped the process that provided\n\
6204the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006205
6206static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006207posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006208{
Victor Stinner8c62be82010-05-06 00:08:46 +00006209 WAIT_TYPE status;
6210 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006211
Victor Stinner8c62be82010-05-06 00:08:46 +00006212 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6213 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006214
Victor Stinner8c62be82010-05-06 00:08:46 +00006215 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006216}
6217#endif /* WSTOPSIG */
6218
6219#endif /* HAVE_SYS_WAIT_H */
6220
6221
Thomas Wouters477c8d52006-05-27 19:21:47 +00006222#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006223#ifdef _SCO_DS
6224/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6225 needed definitions in sys/statvfs.h */
6226#define _SVID3
6227#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006228#include <sys/statvfs.h>
6229
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006230static PyObject*
6231_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006232 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6233 if (v == NULL)
6234 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006235
6236#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006237 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6238 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6239 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6240 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6241 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6242 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6243 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6244 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6245 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6246 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006247#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006248 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6249 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6250 PyStructSequence_SET_ITEM(v, 2,
6251 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6252 PyStructSequence_SET_ITEM(v, 3,
6253 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6254 PyStructSequence_SET_ITEM(v, 4,
6255 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6256 PyStructSequence_SET_ITEM(v, 5,
6257 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6258 PyStructSequence_SET_ITEM(v, 6,
6259 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6260 PyStructSequence_SET_ITEM(v, 7,
6261 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6262 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6263 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006264#endif
6265
Victor Stinner8c62be82010-05-06 00:08:46 +00006266 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006267}
6268
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006269PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006270"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006271Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006272
6273static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006274posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006275{
Victor Stinner8c62be82010-05-06 00:08:46 +00006276 int fd, res;
6277 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006278
Victor Stinner8c62be82010-05-06 00:08:46 +00006279 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6280 return NULL;
6281 Py_BEGIN_ALLOW_THREADS
6282 res = fstatvfs(fd, &st);
6283 Py_END_ALLOW_THREADS
6284 if (res != 0)
6285 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006286
Victor Stinner8c62be82010-05-06 00:08:46 +00006287 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006288}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006289#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006290
6291
Thomas Wouters477c8d52006-05-27 19:21:47 +00006292#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006293#include <sys/statvfs.h>
6294
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006295PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006296"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006297Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006298
6299static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006300posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006301{
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 char *path;
6303 int res;
6304 struct statvfs st;
6305 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6306 return NULL;
6307 Py_BEGIN_ALLOW_THREADS
6308 res = statvfs(path, &st);
6309 Py_END_ALLOW_THREADS
6310 if (res != 0)
6311 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006312
Victor Stinner8c62be82010-05-06 00:08:46 +00006313 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006314}
6315#endif /* HAVE_STATVFS */
6316
Fred Drakec9680921999-12-13 16:37:25 +00006317/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6318 * It maps strings representing configuration variable names to
6319 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006320 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006321 * rarely-used constants. There are three separate tables that use
6322 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006323 *
6324 * This code is always included, even if none of the interfaces that
6325 * need it are included. The #if hackery needed to avoid it would be
6326 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006327 */
6328struct constdef {
6329 char *name;
6330 long value;
6331};
6332
Fred Drake12c6e2d1999-12-14 21:25:03 +00006333static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006334conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006335 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006336{
Christian Heimes217cfd12007-12-02 14:31:20 +00006337 if (PyLong_Check(arg)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 *valuep = PyLong_AS_LONG(arg);
6339 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006340 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006341 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00006342 /* look up the value in the table using a binary search */
6343 size_t lo = 0;
6344 size_t mid;
6345 size_t hi = tablesize;
6346 int cmp;
6347 const char *confname;
6348 if (!PyUnicode_Check(arg)) {
6349 PyErr_SetString(PyExc_TypeError,
6350 "configuration names must be strings or integers");
Guido van Rossumbce56a62007-05-10 18:04:33 +00006351 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006352 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006353 confname = _PyUnicode_AsString(arg);
6354 if (confname == NULL)
6355 return 0;
6356 while (lo < hi) {
6357 mid = (lo + hi) / 2;
6358 cmp = strcmp(confname, table[mid].name);
6359 if (cmp < 0)
6360 hi = mid;
6361 else if (cmp > 0)
6362 lo = mid + 1;
6363 else {
6364 *valuep = table[mid].value;
6365 return 1;
6366 }
6367 }
6368 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6369 return 0;
6370 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006371}
6372
6373
6374#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6375static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006376#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006377 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006378#endif
6379#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006380 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006381#endif
Fred Drakec9680921999-12-13 16:37:25 +00006382#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006383 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006384#endif
6385#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006386 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006387#endif
6388#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006389 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006390#endif
6391#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006392 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006393#endif
6394#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006395 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006396#endif
6397#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006398 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006399#endif
6400#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006401 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006402#endif
6403#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006404 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006405#endif
6406#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006408#endif
6409#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006410 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006411#endif
6412#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006414#endif
6415#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006416 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006417#endif
6418#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006419 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006420#endif
6421#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006422 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006423#endif
6424#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006425 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006426#endif
6427};
6428
Fred Drakec9680921999-12-13 16:37:25 +00006429static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006430conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006431{
6432 return conv_confname(arg, valuep, posix_constants_pathconf,
6433 sizeof(posix_constants_pathconf)
6434 / sizeof(struct constdef));
6435}
6436#endif
6437
6438#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006439PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006440"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006441Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006442If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006443
6444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006445posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006446{
6447 PyObject *result = NULL;
6448 int name, fd;
6449
Fred Drake12c6e2d1999-12-14 21:25:03 +00006450 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6451 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006453
Victor Stinner8c62be82010-05-06 00:08:46 +00006454 errno = 0;
6455 limit = fpathconf(fd, name);
6456 if (limit == -1 && errno != 0)
6457 posix_error();
6458 else
6459 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006460 }
6461 return result;
6462}
6463#endif
6464
6465
6466#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006467PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006468"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006469Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006470If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006471
6472static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006473posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006474{
6475 PyObject *result = NULL;
6476 int name;
6477 char *path;
6478
6479 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6480 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006482
Victor Stinner8c62be82010-05-06 00:08:46 +00006483 errno = 0;
6484 limit = pathconf(path, name);
6485 if (limit == -1 && errno != 0) {
6486 if (errno == EINVAL)
6487 /* could be a path or name problem */
6488 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006489 else
Victor Stinner8c62be82010-05-06 00:08:46 +00006490 posix_error_with_filename(path);
6491 }
6492 else
6493 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006494 }
6495 return result;
6496}
6497#endif
6498
6499#ifdef HAVE_CONFSTR
6500static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006501#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006502 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006503#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006504#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006505 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006506#endif
6507#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006508 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006509#endif
Fred Draked86ed291999-12-15 15:34:33 +00006510#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006511 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006512#endif
6513#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006514 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006515#endif
6516#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006517 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006518#endif
6519#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006520 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006521#endif
Fred Drakec9680921999-12-13 16:37:25 +00006522#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006523 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006524#endif
6525#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006526 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006527#endif
6528#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006529 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006530#endif
6531#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006532 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006533#endif
6534#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006535 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006536#endif
6537#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006538 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006539#endif
6540#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006541 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006542#endif
6543#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006544 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006545#endif
Fred Draked86ed291999-12-15 15:34:33 +00006546#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006547 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006548#endif
Fred Drakec9680921999-12-13 16:37:25 +00006549#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006550 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006551#endif
Fred Draked86ed291999-12-15 15:34:33 +00006552#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006553 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006554#endif
6555#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006556 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006557#endif
6558#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006559 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006560#endif
6561#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006562 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006563#endif
Fred Drakec9680921999-12-13 16:37:25 +00006564#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006566#endif
6567#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006568 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006569#endif
6570#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006571 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006572#endif
6573#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006574 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006575#endif
6576#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006577 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006578#endif
6579#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006580 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006581#endif
6582#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006583 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006584#endif
6585#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006586 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006587#endif
6588#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006589 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006590#endif
6591#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006592 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006593#endif
6594#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006595 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006596#endif
6597#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006598 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006599#endif
6600#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006602#endif
6603#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006605#endif
6606#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006608#endif
6609#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006611#endif
Fred Draked86ed291999-12-15 15:34:33 +00006612#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006614#endif
6615#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006616 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006617#endif
6618#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006619 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006620#endif
6621#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006622 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006623#endif
6624#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006625 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006626#endif
6627#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006629#endif
6630#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006631 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006632#endif
6633#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006634 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006635#endif
6636#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006637 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006638#endif
6639#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006640 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006641#endif
6642#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006643 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006644#endif
6645#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006647#endif
6648#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006650#endif
Fred Drakec9680921999-12-13 16:37:25 +00006651};
6652
6653static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006654conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006655{
6656 return conv_confname(arg, valuep, posix_constants_confstr,
6657 sizeof(posix_constants_confstr)
6658 / sizeof(struct constdef));
6659}
6660
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006661PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006662"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006663Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006664
6665static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006666posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006667{
6668 PyObject *result = NULL;
6669 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00006670 char buffer[255];
Victor Stinner8c62be82010-05-06 00:08:46 +00006671 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006672
Victor Stinnercb043522010-09-10 23:49:04 +00006673 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
6674 return NULL;
6675
6676 errno = 0;
6677 len = confstr(name, buffer, sizeof(buffer));
6678 if (len == 0) {
6679 if (errno) {
6680 posix_error();
6681 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00006682 }
6683 else {
Victor Stinnercb043522010-09-10 23:49:04 +00006684 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00006685 }
6686 }
Victor Stinnercb043522010-09-10 23:49:04 +00006687
6688 if ((unsigned int)len >= sizeof(buffer)) {
6689 char *buf = PyMem_Malloc(len);
6690 if (buf == NULL)
6691 return PyErr_NoMemory();
6692 confstr(name, buf, len);
6693 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
6694 PyMem_Free(buf);
6695 }
6696 else
6697 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006698 return result;
6699}
6700#endif
6701
6702
6703#ifdef HAVE_SYSCONF
6704static struct constdef posix_constants_sysconf[] = {
6705#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00006706 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006707#endif
6708#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00006709 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006710#endif
6711#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006712 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006713#endif
6714#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006715 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006716#endif
6717#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006718 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006719#endif
6720#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00006721 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006722#endif
6723#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00006724 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006725#endif
6726#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006727 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006728#endif
6729#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00006730 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006731#endif
6732#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006733 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006734#endif
Fred Draked86ed291999-12-15 15:34:33 +00006735#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006736 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006737#endif
6738#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00006739 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006740#endif
Fred Drakec9680921999-12-13 16:37:25 +00006741#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006742 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006743#endif
Fred Drakec9680921999-12-13 16:37:25 +00006744#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006745 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006746#endif
6747#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006748 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006749#endif
6750#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006751 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006752#endif
6753#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006754 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006755#endif
6756#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006757 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006758#endif
Fred Draked86ed291999-12-15 15:34:33 +00006759#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006761#endif
Fred Drakec9680921999-12-13 16:37:25 +00006762#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006763 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006764#endif
6765#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006766 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006767#endif
6768#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006769 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006770#endif
6771#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006772 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006773#endif
6774#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006775 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006776#endif
Fred Draked86ed291999-12-15 15:34:33 +00006777#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006779#endif
Fred Drakec9680921999-12-13 16:37:25 +00006780#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006782#endif
6783#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006785#endif
6786#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006787 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006788#endif
6789#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006790 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006791#endif
6792#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006793 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006794#endif
6795#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006797#endif
6798#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006800#endif
6801#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006803#endif
6804#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006806#endif
6807#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006809#endif
6810#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006811 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006812#endif
6813#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006814 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006815#endif
6816#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006818#endif
6819#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006821#endif
6822#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006824#endif
6825#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006827#endif
6828#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006829 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006830#endif
6831#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006832 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006833#endif
6834#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006836#endif
6837#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006839#endif
6840#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006842#endif
6843#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006845#endif
6846#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006848#endif
Fred Draked86ed291999-12-15 15:34:33 +00006849#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006851#endif
Fred Drakec9680921999-12-13 16:37:25 +00006852#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006854#endif
6855#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006856 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006857#endif
6858#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006860#endif
Fred Draked86ed291999-12-15 15:34:33 +00006861#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006863#endif
Fred Drakec9680921999-12-13 16:37:25 +00006864#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006866#endif
Fred Draked86ed291999-12-15 15:34:33 +00006867#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006869#endif
6870#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006872#endif
Fred Drakec9680921999-12-13 16:37:25 +00006873#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006875#endif
6876#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006878#endif
6879#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006880 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006881#endif
6882#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006883 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006884#endif
Fred Draked86ed291999-12-15 15:34:33 +00006885#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00006886 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006887#endif
Fred Drakec9680921999-12-13 16:37:25 +00006888#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006890#endif
6891#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006893#endif
6894#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006895 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006896#endif
6897#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006899#endif
6900#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006902#endif
6903#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00006904 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006905#endif
6906#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006908#endif
Fred Draked86ed291999-12-15 15:34:33 +00006909#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006911#endif
Fred Drakec9680921999-12-13 16:37:25 +00006912#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006914#endif
6915#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006916 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006917#endif
Fred Draked86ed291999-12-15 15:34:33 +00006918#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006919 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006920#endif
Fred Drakec9680921999-12-13 16:37:25 +00006921#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006922 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006923#endif
6924#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006926#endif
6927#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006928 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006929#endif
6930#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006931 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006932#endif
6933#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006934 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006935#endif
6936#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006937 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006938#endif
6939#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006940 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006941#endif
6942#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006943 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00006944#endif
6945#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00006946 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00006947#endif
Fred Draked86ed291999-12-15 15:34:33 +00006948#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00006950#endif
6951#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00006952 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00006953#endif
Fred Drakec9680921999-12-13 16:37:25 +00006954#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00006955 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00006956#endif
6957#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006959#endif
6960#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006961 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006962#endif
6963#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006964 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006965#endif
6966#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006968#endif
6969#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006970 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006971#endif
6972#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00006973 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00006974#endif
6975#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00006977#endif
6978#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00006979 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00006980#endif
6981#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00006982 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00006983#endif
6984#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00006985 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00006986#endif
6987#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006988 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00006989#endif
6990#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006991 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00006992#endif
6993#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00006994 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00006995#endif
6996#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00006997 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00006998#endif
6999#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00007000 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00007001#endif
7002#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00007003 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00007004#endif
7005#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007006 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007007#endif
7008#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007009 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007010#endif
7011#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00007012 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00007013#endif
7014#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007015 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007016#endif
7017#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007019#endif
7020#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00007021 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00007022#endif
7023#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007024 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007025#endif
7026#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007027 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007028#endif
7029#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00007031#endif
7032#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00007033 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00007034#endif
7035#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007036 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007037#endif
7038#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007039 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007040#endif
7041#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007042 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00007043#endif
7044#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007045 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007046#endif
7047#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007048 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007049#endif
7050#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007052#endif
7053#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007055#endif
7056#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007057 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007058#endif
Fred Draked86ed291999-12-15 15:34:33 +00007059#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00007060 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00007061#endif
Fred Drakec9680921999-12-13 16:37:25 +00007062#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00007063 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00007064#endif
7065#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007066 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007067#endif
7068#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00007069 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00007070#endif
7071#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007072 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007073#endif
7074#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007076#endif
7077#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007079#endif
7080#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00007081 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00007082#endif
7083#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007085#endif
7086#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007088#endif
7089#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007090 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007091#endif
7092#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007093 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007094#endif
7095#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007096 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00007097#endif
7098#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007099 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00007100#endif
7101#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00007102 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00007103#endif
7104#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007105 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007106#endif
7107#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007108 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007109#endif
7110#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007112#endif
7113#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007114 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00007115#endif
7116#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007117 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007118#endif
7119#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007120 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007121#endif
7122#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007123 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007124#endif
7125#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007126 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007127#endif
7128#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007129 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007130#endif
7131#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007132 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007133#endif
7134#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007135 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007136#endif
7137#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007138 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007139#endif
7140#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007141 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007142#endif
7143#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007144 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007145#endif
7146#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007147 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007148#endif
7149#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007150 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007151#endif
7152#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007153 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007154#endif
7155#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007156 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007157#endif
7158#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007160#endif
7161#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007162 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007163#endif
7164#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007166#endif
7167#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007168 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007169#endif
7170#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007171 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007172#endif
7173#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007174 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007175#endif
7176#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007177 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007178#endif
7179#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007180 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007181#endif
7182#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007183 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007184#endif
7185#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007186 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007187#endif
7188#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007189 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007190#endif
7191#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007192 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007193#endif
7194#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007195 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007196#endif
7197};
7198
7199static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007200conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007201{
7202 return conv_confname(arg, valuep, posix_constants_sysconf,
7203 sizeof(posix_constants_sysconf)
7204 / sizeof(struct constdef));
7205}
7206
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007207PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007208"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007209Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007210
7211static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007212posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007213{
7214 PyObject *result = NULL;
7215 int name;
7216
7217 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7218 int value;
7219
7220 errno = 0;
7221 value = sysconf(name);
7222 if (value == -1 && errno != 0)
7223 posix_error();
7224 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007225 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007226 }
7227 return result;
7228}
7229#endif
7230
7231
Fred Drakebec628d1999-12-15 18:31:10 +00007232/* This code is used to ensure that the tables of configuration value names
7233 * are in sorted order as required by conv_confname(), and also to build the
7234 * the exported dictionaries that are used to publish information about the
7235 * names available on the host platform.
7236 *
7237 * Sorting the table at runtime ensures that the table is properly ordered
7238 * when used, even for platforms we're not able to test on. It also makes
7239 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007240 */
Fred Drakebec628d1999-12-15 18:31:10 +00007241
7242static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007243cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007244{
7245 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007246 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007247 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007248 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007249
7250 return strcmp(c1->name, c2->name);
7251}
7252
7253static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007254setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007255 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007256{
Fred Drakebec628d1999-12-15 18:31:10 +00007257 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007258 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007259
7260 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7261 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007262 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007263 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007264
Barry Warsaw3155db32000-04-13 15:20:40 +00007265 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007266 PyObject *o = PyLong_FromLong(table[i].value);
7267 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7268 Py_XDECREF(o);
7269 Py_DECREF(d);
7270 return -1;
7271 }
7272 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007273 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007274 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007275}
7276
Fred Drakebec628d1999-12-15 18:31:10 +00007277/* Return -1 on failure, 0 on success. */
7278static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007279setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007280{
7281#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007282 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007283 sizeof(posix_constants_pathconf)
7284 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007285 "pathconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007286 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007287#endif
7288#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007289 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007290 sizeof(posix_constants_confstr)
7291 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007292 "confstr_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007293 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007294#endif
7295#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007296 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007297 sizeof(posix_constants_sysconf)
7298 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007299 "sysconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007300 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007301#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007302 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007303}
Fred Draked86ed291999-12-15 15:34:33 +00007304
7305
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007306PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007307"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007308Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007309in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007310
7311static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007312posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007313{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007314 abort();
7315 /*NOTREACHED*/
7316 Py_FatalError("abort() called from Python code didn't abort!");
7317 return NULL;
7318}
Fred Drakebec628d1999-12-15 18:31:10 +00007319
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007320#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007321PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007322"startfile(filepath [, operation]) - Start a file with its associated\n\
7323application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007324\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007325When \"operation\" is not specified or \"open\", this acts like\n\
7326double-clicking the file in Explorer, or giving the file name as an\n\
7327argument to the DOS \"start\" command: the file is opened with whatever\n\
7328application (if any) its extension is associated.\n\
7329When another \"operation\" is given, it specifies what should be done with\n\
7330the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007331\n\
7332startfile returns as soon as the associated application is launched.\n\
7333There is no option to wait for the application to close, and no way\n\
7334to retrieve the application's exit status.\n\
7335\n\
7336The filepath is relative to the current directory. If you want to use\n\
7337an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007338the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007339
7340static PyObject *
7341win32_startfile(PyObject *self, PyObject *args)
7342{
Victor Stinner8c62be82010-05-06 00:08:46 +00007343 PyObject *ofilepath;
7344 char *filepath;
7345 char *operation = NULL;
7346 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007347
Victor Stinner8c62be82010-05-06 00:08:46 +00007348 PyObject *unipath, *woperation = NULL;
7349 if (!PyArg_ParseTuple(args, "U|s:startfile",
7350 &unipath, &operation)) {
7351 PyErr_Clear();
7352 goto normal;
7353 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007354
Victor Stinner8c62be82010-05-06 00:08:46 +00007355 if (operation) {
7356 woperation = PyUnicode_DecodeASCII(operation,
7357 strlen(operation), NULL);
7358 if (!woperation) {
7359 PyErr_Clear();
7360 operation = NULL;
7361 goto normal;
7362 }
7363 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007364
Victor Stinner8c62be82010-05-06 00:08:46 +00007365 Py_BEGIN_ALLOW_THREADS
7366 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7367 PyUnicode_AS_UNICODE(unipath),
7368 NULL, NULL, SW_SHOWNORMAL);
7369 Py_END_ALLOW_THREADS
7370
7371 Py_XDECREF(woperation);
7372 if (rc <= (HINSTANCE)32) {
7373 PyObject *errval = win32_error_unicode("startfile",
7374 PyUnicode_AS_UNICODE(unipath));
7375 return errval;
7376 }
7377 Py_INCREF(Py_None);
7378 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007379
7380normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007381 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7382 PyUnicode_FSConverter, &ofilepath,
7383 &operation))
7384 return NULL;
7385 filepath = PyBytes_AsString(ofilepath);
7386 Py_BEGIN_ALLOW_THREADS
7387 rc = ShellExecute((HWND)0, operation, filepath,
7388 NULL, NULL, SW_SHOWNORMAL);
7389 Py_END_ALLOW_THREADS
7390 if (rc <= (HINSTANCE)32) {
7391 PyObject *errval = win32_error("startfile", filepath);
7392 Py_DECREF(ofilepath);
7393 return errval;
7394 }
7395 Py_DECREF(ofilepath);
7396 Py_INCREF(Py_None);
7397 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007398}
7399#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007400
Martin v. Löwis438b5342002-12-27 10:16:42 +00007401#ifdef HAVE_GETLOADAVG
7402PyDoc_STRVAR(posix_getloadavg__doc__,
7403"getloadavg() -> (float, float, float)\n\n\
7404Return the number of processes in the system run queue averaged over\n\
7405the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7406was unobtainable");
7407
7408static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007409posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007410{
7411 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007412 if (getloadavg(loadavg, 3)!=3) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007413 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7414 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007415 } else
Victor Stinner8c62be82010-05-06 00:08:46 +00007416 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007417}
7418#endif
7419
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007420#ifdef MS_WINDOWS
7421
7422PyDoc_STRVAR(win32_urandom__doc__,
7423"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007424Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007425
7426typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7427 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7428 DWORD dwFlags );
7429typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7430 BYTE *pbBuffer );
7431
7432static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007433/* This handle is never explicitly released. Instead, the operating
7434 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007435static HCRYPTPROV hCryptProv = 0;
7436
Tim Peters4ad82172004-08-30 17:02:04 +00007437static PyObject*
7438win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007439{
Victor Stinner8c62be82010-05-06 00:08:46 +00007440 int howMany;
7441 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007442
Victor Stinner8c62be82010-05-06 00:08:46 +00007443 /* Read arguments */
7444 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7445 return NULL;
7446 if (howMany < 0)
7447 return PyErr_Format(PyExc_ValueError,
7448 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007449
Victor Stinner8c62be82010-05-06 00:08:46 +00007450 if (hCryptProv == 0) {
7451 HINSTANCE hAdvAPI32 = NULL;
7452 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007453
Victor Stinner8c62be82010-05-06 00:08:46 +00007454 /* Obtain handle to the DLL containing CryptoAPI
7455 This should not fail */
7456 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7457 if(hAdvAPI32 == NULL)
7458 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007459
Victor Stinner8c62be82010-05-06 00:08:46 +00007460 /* Obtain pointers to the CryptoAPI functions
7461 This will fail on some early versions of Win95 */
7462 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7463 hAdvAPI32,
7464 "CryptAcquireContextA");
7465 if (pCryptAcquireContext == NULL)
7466 return PyErr_Format(PyExc_NotImplementedError,
7467 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007468
Victor Stinner8c62be82010-05-06 00:08:46 +00007469 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7470 hAdvAPI32, "CryptGenRandom");
7471 if (pCryptGenRandom == NULL)
7472 return PyErr_Format(PyExc_NotImplementedError,
7473 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007474
Victor Stinner8c62be82010-05-06 00:08:46 +00007475 /* Acquire context */
7476 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7477 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7478 return win32_error("CryptAcquireContext", NULL);
7479 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007480
Victor Stinner8c62be82010-05-06 00:08:46 +00007481 /* Allocate bytes */
7482 result = PyBytes_FromStringAndSize(NULL, howMany);
7483 if (result != NULL) {
7484 /* Get random data */
7485 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7486 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7487 PyBytes_AS_STRING(result))) {
7488 Py_DECREF(result);
7489 return win32_error("CryptGenRandom", NULL);
7490 }
7491 }
7492 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007493}
7494#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007495
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007496PyDoc_STRVAR(device_encoding__doc__,
7497"device_encoding(fd) -> str\n\n\
7498Return a string describing the encoding of the device\n\
7499if the output is a terminal; else return None.");
7500
7501static PyObject *
7502device_encoding(PyObject *self, PyObject *args)
7503{
Victor Stinner8c62be82010-05-06 00:08:46 +00007504 int fd;
7505 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7506 return NULL;
7507 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7508 Py_INCREF(Py_None);
7509 return Py_None;
7510 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007511#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007512 if (fd == 0) {
7513 char buf[100];
7514 sprintf(buf, "cp%d", GetConsoleCP());
7515 return PyUnicode_FromString(buf);
7516 }
7517 if (fd == 1 || fd == 2) {
7518 char buf[100];
7519 sprintf(buf, "cp%d", GetConsoleOutputCP());
7520 return PyUnicode_FromString(buf);
7521 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007522#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007523 {
7524 char *codeset = nl_langinfo(CODESET);
7525 if (codeset != NULL && codeset[0] != 0)
7526 return PyUnicode_FromString(codeset);
7527 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007528#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007529 Py_INCREF(Py_None);
7530 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007531}
7532
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007533#ifdef __VMS
7534/* Use openssl random routine */
7535#include <openssl/rand.h>
7536PyDoc_STRVAR(vms_urandom__doc__,
7537"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007538Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007539
7540static PyObject*
7541vms_urandom(PyObject *self, PyObject *args)
7542{
Victor Stinner8c62be82010-05-06 00:08:46 +00007543 int howMany;
7544 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007545
Victor Stinner8c62be82010-05-06 00:08:46 +00007546 /* Read arguments */
7547 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7548 return NULL;
7549 if (howMany < 0)
7550 return PyErr_Format(PyExc_ValueError,
7551 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007552
Victor Stinner8c62be82010-05-06 00:08:46 +00007553 /* Allocate bytes */
7554 result = PyBytes_FromStringAndSize(NULL, howMany);
7555 if (result != NULL) {
7556 /* Get random data */
7557 if (RAND_pseudo_bytes((unsigned char*)
7558 PyBytes_AS_STRING(result),
7559 howMany) < 0) {
7560 Py_DECREF(result);
7561 return PyErr_Format(PyExc_ValueError,
7562 "RAND_pseudo_bytes");
7563 }
7564 }
7565 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007566}
7567#endif
7568
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007569#ifdef HAVE_SETRESUID
7570PyDoc_STRVAR(posix_setresuid__doc__,
7571"setresuid(ruid, euid, suid)\n\n\
7572Set the current process's real, effective, and saved user ids.");
7573
7574static PyObject*
7575posix_setresuid (PyObject *self, PyObject *args)
7576{
Victor Stinner8c62be82010-05-06 00:08:46 +00007577 /* We assume uid_t is no larger than a long. */
7578 long ruid, euid, suid;
7579 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7580 return NULL;
7581 if (setresuid(ruid, euid, suid) < 0)
7582 return posix_error();
7583 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007584}
7585#endif
7586
7587#ifdef HAVE_SETRESGID
7588PyDoc_STRVAR(posix_setresgid__doc__,
7589"setresgid(rgid, egid, sgid)\n\n\
7590Set the current process's real, effective, and saved group ids.");
7591
7592static PyObject*
7593posix_setresgid (PyObject *self, PyObject *args)
7594{
Victor Stinner8c62be82010-05-06 00:08:46 +00007595 /* We assume uid_t is no larger than a long. */
7596 long rgid, egid, sgid;
7597 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7598 return NULL;
7599 if (setresgid(rgid, egid, sgid) < 0)
7600 return posix_error();
7601 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007602}
7603#endif
7604
7605#ifdef HAVE_GETRESUID
7606PyDoc_STRVAR(posix_getresuid__doc__,
7607"getresuid() -> (ruid, euid, suid)\n\n\
7608Get tuple of the current process's real, effective, and saved user ids.");
7609
7610static PyObject*
7611posix_getresuid (PyObject *self, PyObject *noargs)
7612{
Victor Stinner8c62be82010-05-06 00:08:46 +00007613 uid_t ruid, euid, suid;
7614 long l_ruid, l_euid, l_suid;
7615 if (getresuid(&ruid, &euid, &suid) < 0)
7616 return posix_error();
7617 /* Force the values into long's as we don't know the size of uid_t. */
7618 l_ruid = ruid;
7619 l_euid = euid;
7620 l_suid = suid;
7621 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007622}
7623#endif
7624
7625#ifdef HAVE_GETRESGID
7626PyDoc_STRVAR(posix_getresgid__doc__,
7627"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00007628Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007629
7630static PyObject*
7631posix_getresgid (PyObject *self, PyObject *noargs)
7632{
Victor Stinner8c62be82010-05-06 00:08:46 +00007633 uid_t rgid, egid, sgid;
7634 long l_rgid, l_egid, l_sgid;
7635 if (getresgid(&rgid, &egid, &sgid) < 0)
7636 return posix_error();
7637 /* Force the values into long's as we don't know the size of uid_t. */
7638 l_rgid = rgid;
7639 l_egid = egid;
7640 l_sgid = sgid;
7641 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007642}
7643#endif
7644
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007645static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007646 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007647#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007648 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007649#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007650 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007651#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007652 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007653#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007654 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007655#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007656 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007657#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007658#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007659 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007660#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007661#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007662 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007663#endif /* HAVE_LCHMOD */
7664#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007665 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007666#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007667#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007668 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007669#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007670#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007671 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007672#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007673#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007674 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007675#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007676#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007677 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007678#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007679#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00007680 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7681 METH_NOARGS, posix_getcwd__doc__},
7682 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7683 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007684#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007685#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007686 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007687#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00007688 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7689 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7690 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007691#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00007692 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007693#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007694#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007695 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007696#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007697#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007698 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007699#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007700 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7701 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7702 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00007703 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007704#ifdef HAVE_SYMLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007705 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007706#endif /* HAVE_SYMLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007707#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin74e45612010-07-09 15:58:59 +00007708 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
7709 win_symlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007710#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007711#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00007712 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007713#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007714 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007715#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007716 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007717#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00007718 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7719 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7720 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007721#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00007722 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007723#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00007724 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007725#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00007726 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7727 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007728#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007729#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00007730 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7731 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007732#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00007733 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7734 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007735#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007736#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007737#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00007738 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007739#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007740#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00007741 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007742#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007743#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00007744 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007745#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007746#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007747 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007748#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007749#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007750 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007751#endif /* HAVE_GETEGID */
7752#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007753 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007754#endif /* HAVE_GETEUID */
7755#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007756 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007757#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007758#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007759 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007760#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007761 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007762#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007763 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007764#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007765#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007766 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007767#endif /* HAVE_GETPPID */
7768#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007770#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007771#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007772 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007773#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007774#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007776#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007777#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00007778 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007779#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007780#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007781 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007782#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007783#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7785 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007786#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007787#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007788 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007789#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007790#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007792#endif /* HAVE_SETEUID */
7793#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007795#endif /* HAVE_SETEGID */
7796#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007797 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007798#endif /* HAVE_SETREUID */
7799#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007800 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007801#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007802#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007803 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007804#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007805#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007806 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007807#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00007808#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007809 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00007810#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007811#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007812 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007813#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007814#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007815 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007816#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007817#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007818 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007819#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007820#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00007821 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007822#endif /* HAVE_WAIT3 */
7823#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00007824 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007825#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007826#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007827 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007828#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007829#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007830 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007831#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007832#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007833 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007834#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007835#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007836 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007837#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007838#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007839 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007840#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007841#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007842 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007843#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00007844 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7845 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7846 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7847 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7848 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7849 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7850 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7851 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7852 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7853 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7854 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007855#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00007856 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007857#endif
7858#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007860#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007861#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007863#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007864#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00007865 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7866 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7867 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007868#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007869#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00007870 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007871#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007872#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007874#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007875#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007876 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007877#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007878 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007879#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00007880 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007881#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007882#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007883 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007884#endif
7885#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007886 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007887#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007888#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007889#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00007890 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007891#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007892#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00007893 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007894#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007895#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00007896 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007897#endif /* WIFSTOPPED */
7898#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00007899 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007900#endif /* WIFSIGNALED */
7901#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00007902 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007903#endif /* WIFEXITED */
7904#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00007905 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007906#endif /* WEXITSTATUS */
7907#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007908 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007909#endif /* WTERMSIG */
7910#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007911 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007912#endif /* WSTOPSIG */
7913#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007914#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007915 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007916#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007917#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007918 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007919#endif
Fred Drakec9680921999-12-13 16:37:25 +00007920#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00007921 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007922#endif
7923#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007924 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007925#endif
7926#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007927 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007928#endif
7929#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007930 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007931#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007932 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007933#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00007935 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +00007936 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00007937#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007938#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00007939 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007940#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007941 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007942 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007943 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007944 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007945 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007946 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007947#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007948 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007949#endif
7950#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007951 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007952#endif
7953#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007954 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007955#endif
7956#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007957 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007958#endif
7959
Victor Stinner8c62be82010-05-06 00:08:46 +00007960 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007961};
7962
7963
Barry Warsaw4a342091996-12-19 23:50:02 +00007964static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007965ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007966{
Victor Stinner8c62be82010-05-06 00:08:46 +00007967 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007968}
7969
Guido van Rossumd48f2521997-12-05 22:19:34 +00007970#if defined(PYOS_OS2)
7971/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007972static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007973{
7974 APIRET rc;
7975 ULONG values[QSV_MAX+1];
7976 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007977 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007978
7979 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007980 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007981 Py_END_ALLOW_THREADS
7982
7983 if (rc != NO_ERROR) {
7984 os2_error(rc);
7985 return -1;
7986 }
7987
Fred Drake4d1e64b2002-04-15 19:40:07 +00007988 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7989 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7990 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7991 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7992 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7993 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7994 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007995
7996 switch (values[QSV_VERSION_MINOR]) {
7997 case 0: ver = "2.00"; break;
7998 case 10: ver = "2.10"; break;
7999 case 11: ver = "2.11"; break;
8000 case 30: ver = "3.00"; break;
8001 case 40: ver = "4.00"; break;
8002 case 50: ver = "5.00"; break;
8003 default:
Tim Peters885d4572001-11-28 20:27:42 +00008004 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00008005 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00008006 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008007 ver = &tmp[0];
8008 }
8009
8010 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008011 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008012 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008013
8014 /* Add Indicator of Which Drive was Used to Boot the System */
8015 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8016 tmp[1] = ':';
8017 tmp[2] = '\0';
8018
Fred Drake4d1e64b2002-04-15 19:40:07 +00008019 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008020}
8021#endif
8022
Barry Warsaw4a342091996-12-19 23:50:02 +00008023static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008024all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008025{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008026#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008027 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008028#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008029#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008030 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008031#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008032#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008033 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008034#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008035#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008036 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008037#endif
Fred Drakec9680921999-12-13 16:37:25 +00008038#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008039 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00008040#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008041#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008042 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008043#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008044#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008045 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008046#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008047#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00008048 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008049#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008050#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00008051 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008052#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008053#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008054 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008055#endif
8056#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008057 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008058#endif
8059#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00008060 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008061#endif
8062#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00008063 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008064#endif
8065#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008066 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008067#endif
8068#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00008069 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008070#endif
8071#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008072 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008073#endif
8074#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008075 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008076#endif
8077#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008078 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008079#endif
8080#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008081 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008082#endif
8083#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008084 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008085#endif
8086#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00008087 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008088#endif
8089#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008090 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008091#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008092#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008093 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008094#endif
8095#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00008096 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008097#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008098#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008099 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008100#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008101#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008102 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008103#endif
8104#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008105 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008106#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008107
Tim Peters5aa91602002-01-30 05:46:57 +00008108/* MS Windows */
8109#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008110 /* Don't inherit in child processes. */
8111 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008112#endif
8113#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00008114 /* Optimize for short life (keep in memory). */
8115 /* MS forgot to define this one with a non-underscore form too. */
8116 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008117#endif
8118#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008119 /* Automatically delete when last handle is closed. */
8120 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008121#endif
8122#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008123 /* Optimize for random access. */
8124 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008125#endif
8126#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008127 /* Optimize for sequential access. */
8128 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008129#endif
8130
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008131/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008132#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008133 /* Send a SIGIO signal whenever input or output
8134 becomes available on file descriptor */
8135 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008136#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008137#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008138 /* Direct disk access. */
8139 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008140#endif
8141#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008142 /* Must be a directory. */
8143 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008144#endif
8145#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008146 /* Do not follow links. */
8147 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008148#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008149#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008150 /* Do not update the access time. */
8151 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008152#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008153
Victor Stinner8c62be82010-05-06 00:08:46 +00008154 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008155#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008156 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008157#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008158#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008159 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008160#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008161#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008162 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008163#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008164#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008165 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008166#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008167#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008168 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008169#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008170#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008171 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008172#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008173#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008174 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008175#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008176#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008177 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008178#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008179#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008180 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008181#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008182#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008183 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008184#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008185#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008186 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008187#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008188#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008189 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008190#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008191#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008192 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008193#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008194#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008195 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008196#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008197#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008198 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008199#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008200#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008201 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008202#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008203#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008204 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008205#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008206
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008207 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008208#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008209 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008210#endif /* ST_RDONLY */
8211#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008212 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008213#endif /* ST_NOSUID */
8214
Guido van Rossum246bc171999-02-01 23:54:31 +00008215#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008216#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008217 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8218 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8219 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8220 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8221 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8222 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8223 if (ins(d, "P_PM", (long)P_PM)) return -1;
8224 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8225 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8226 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8227 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8228 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8229 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8230 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8231 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8232 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8233 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8234 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8235 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8236 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008237#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008238 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8239 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8240 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8241 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8242 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008243#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008244#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008245
Guido van Rossumd48f2521997-12-05 22:19:34 +00008246#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008247 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008248#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008249 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008250}
8251
8252
Tim Peters5aa91602002-01-30 05:46:57 +00008253#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008254#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008255#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008256
8257#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008258#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008259#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008260
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008261#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008262#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008263#define MODNAME "posix"
8264#endif
8265
Martin v. Löwis1a214512008-06-11 05:26:20 +00008266static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008267 PyModuleDef_HEAD_INIT,
8268 MODNAME,
8269 posix__doc__,
8270 -1,
8271 posix_methods,
8272 NULL,
8273 NULL,
8274 NULL,
8275 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008276};
8277
8278
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008279PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008280INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008281{
Victor Stinner8c62be82010-05-06 00:08:46 +00008282 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008283
Victor Stinner8c62be82010-05-06 00:08:46 +00008284 m = PyModule_Create(&posixmodule);
8285 if (m == NULL)
8286 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008287
Victor Stinner8c62be82010-05-06 00:08:46 +00008288 /* Initialize environ dictionary */
8289 v = convertenviron();
8290 Py_XINCREF(v);
8291 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8292 return NULL;
8293 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008294
Victor Stinner8c62be82010-05-06 00:08:46 +00008295 if (all_ins(m))
8296 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008297
Victor Stinner8c62be82010-05-06 00:08:46 +00008298 if (setup_confname_tables(m))
8299 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008300
Victor Stinner8c62be82010-05-06 00:08:46 +00008301 Py_INCREF(PyExc_OSError);
8302 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008303
Guido van Rossumb3d39562000-01-31 18:41:26 +00008304#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008305 if (posix_putenv_garbage == NULL)
8306 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008307#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008308
Victor Stinner8c62be82010-05-06 00:08:46 +00008309 if (!initialized) {
8310 stat_result_desc.name = MODNAME ".stat_result";
8311 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8312 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8313 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8314 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8315 structseq_new = StatResultType.tp_new;
8316 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008317
Victor Stinner8c62be82010-05-06 00:08:46 +00008318 statvfs_result_desc.name = MODNAME ".statvfs_result";
8319 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008320#ifdef NEED_TICKS_PER_SECOND
8321# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008322 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008323# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008324 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008325# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008326 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008327# endif
8328#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008329 }
8330 Py_INCREF((PyObject*) &StatResultType);
8331 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8332 Py_INCREF((PyObject*) &StatVFSResultType);
8333 PyModule_AddObject(m, "statvfs_result",
8334 (PyObject*) &StatVFSResultType);
8335 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008336
8337#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008338 /*
8339 * Step 2 of weak-linking support on Mac OS X.
8340 *
8341 * The code below removes functions that are not available on the
8342 * currently active platform.
8343 *
8344 * This block allow one to use a python binary that was build on
8345 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8346 * OSX 10.4.
8347 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008348#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008349 if (fstatvfs == NULL) {
8350 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8351 return NULL;
8352 }
8353 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008354#endif /* HAVE_FSTATVFS */
8355
8356#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008357 if (statvfs == NULL) {
8358 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8359 return NULL;
8360 }
8361 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008362#endif /* HAVE_STATVFS */
8363
8364# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008365 if (lchown == NULL) {
8366 if (PyObject_DelAttrString(m, "lchown") == -1) {
8367 return NULL;
8368 }
8369 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008370#endif /* HAVE_LCHOWN */
8371
8372
8373#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008374 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008375
Guido van Rossumb6775db1994-08-01 11:34:53 +00008376}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008377
8378#ifdef __cplusplus
8379}
8380#endif