blob: 929436db6e0895a71134b940171570417b0f5ddd [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
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000125#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000126#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000127#define HAVE_EXECV 1
128#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000129#define HAVE_SYSTEM 1
130#define HAVE_CWAIT 1
131#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000132#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000133#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000134#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
135/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000136#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137/* Unix functions that the configure script doesn't check for */
138#define HAVE_EXECV 1
139#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000140#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000141#define HAVE_FORK1 1
142#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#define HAVE_GETCWD 1
144#define HAVE_GETEGID 1
145#define HAVE_GETEUID 1
146#define HAVE_GETGID 1
147#define HAVE_GETPPID 1
148#define HAVE_GETUID 1
149#define HAVE_KILL 1
150#define HAVE_OPENDIR 1
151#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000154#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000155#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156#endif /* _MSC_VER */
157#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000158#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000159#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000160
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000161#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000162
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000163#if defined(__sgi)&&_COMPILER_VERSION>=700
164/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
165 (default) */
166extern char *ctermid_r(char *);
167#endif
168
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000169#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000170#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000171extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000172#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000173#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000176extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000178#endif
179#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000180extern int chdir(char *);
181extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000182#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000183extern int chdir(const char *);
184extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000185#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000186#ifdef __BORLANDC__
187extern int chmod(const char *, int);
188#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000189extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000190#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000191/*#ifdef HAVE_FCHMOD
192extern int fchmod(int, mode_t);
193#endif*/
194/*#ifdef HAVE_LCHMOD
195extern int lchmod(const char *, mode_t);
196#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000197extern int chown(const char *, uid_t, gid_t);
198extern char *getcwd(char *, int);
199extern char *strerror(int);
200extern int link(const char *, const char *);
201extern int rename(const char *, const char *);
202extern int stat(const char *, struct stat *);
203extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000205extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000206#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000209#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000210#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000211
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000212#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#ifdef HAVE_UTIME_H
215#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000216#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000218#ifdef HAVE_SYS_UTIME_H
219#include <sys/utime.h>
220#define HAVE_UTIME_H /* pretend we do for the rest of this file */
221#endif /* HAVE_SYS_UTIME_H */
222
Guido van Rossumb6775db1994-08-01 11:34:53 +0000223#ifdef HAVE_SYS_TIMES_H
224#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000225#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
227#ifdef HAVE_SYS_PARAM_H
228#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230
231#ifdef HAVE_SYS_UTSNAME_H
232#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000233#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000237#define NAMLEN(dirent) strlen((dirent)->d_name)
238#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000239#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#include <direct.h>
241#define NAMLEN(dirent) strlen((dirent)->d_name)
242#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000245#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000248#endif
249#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000250#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000251#endif
252#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000254#endif
255#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000257#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000258#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000260#endif
261#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000263#endif
264#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000266#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000267#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000268#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000269#endif
270#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000271#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000272#endif
273#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000274#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000275#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000276#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000277#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000279#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000280#include <lmcons.h> /* for UNLEN */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000281#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282
Guido van Rossumd48f2521997-12-05 22:19:34 +0000283#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000285#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286
Tim Petersbc2e10e2002-03-03 23:17:02 +0000287#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000288#if defined(PATH_MAX) && PATH_MAX > 1024
289#define MAXPATHLEN PATH_MAX
290#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000291#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000292#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000293#endif /* MAXPATHLEN */
294
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000295#ifdef UNION_WAIT
296/* Emulate some macros on systems that have a union instead of macros */
297
298#ifndef WIFEXITED
299#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
300#endif
301
302#ifndef WEXITSTATUS
303#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
304#endif
305
306#ifndef WTERMSIG
307#define WTERMSIG(u_wait) ((u_wait).w_termsig)
308#endif
309
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000310#define WAIT_TYPE union wait
311#define WAIT_STATUS_INT(s) (s.w_status)
312
313#else /* !UNION_WAIT */
314#define WAIT_TYPE int
315#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000316#endif /* UNION_WAIT */
317
Greg Wardb48bc172000-03-01 21:51:56 +0000318/* Don't use the "_r" form if we don't need it (also, won't have a
319 prototype for it, at least on Solaris -- maybe others as well?). */
320#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
321#define USE_CTERMID_R
322#endif
323
Fred Drake699f3522000-06-29 21:12:41 +0000324/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000325#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000326#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000327# define STAT win32_stat
328# define FSTAT win32_fstat
329# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000330#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000331# define STAT stat
332# define FSTAT fstat
333# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000334#endif
335
Tim Peters11b23062003-04-23 02:39:17 +0000336#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000337#include <sys/mkdev.h>
338#else
339#if defined(MAJOR_IN_SYSMACROS)
340#include <sys/sysmacros.h>
341#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000342#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
343#include <sys/mkdev.h>
344#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000345#endif
Fred Drake699f3522000-06-29 21:12:41 +0000346
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000347#if defined _MSC_VER && _MSC_VER >= 1400
348/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
349 * valid and throw an assertion if it isn't.
350 * Normally, an invalid fd is likely to be a C program error and therefore
351 * an assertion can be useful, but it does contradict the POSIX standard
352 * which for write(2) states:
353 * "Otherwise, -1 shall be returned and errno set to indicate the error."
354 * "[EBADF] The fildes argument is not a valid file descriptor open for
355 * writing."
356 * Furthermore, python allows the user to enter any old integer
357 * as a fd and should merely raise a python exception on error.
358 * The Microsoft CRT doesn't provide an official way to check for the
359 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000360 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000361 * internal structures involved.
362 * The structures below must be updated for each version of visual studio
363 * according to the file internal.h in the CRT source, until MS comes
364 * up with a less hacky way to do this.
365 * (all of this is to avoid globally modifying the CRT behaviour using
366 * _set_invalid_parameter_handler() and _CrtSetReportMode())
367 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000368/* The actual size of the structure is determined at runtime.
369 * Only the first items must be present.
370 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000371typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000372 intptr_t osfhnd;
373 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000374} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000375
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000376extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000377#define IOINFO_L2E 5
378#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
379#define IOINFO_ARRAYS 64
380#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
381#define FOPEN 0x01
382#define _NO_CONSOLE_FILENO (intptr_t)-2
383
384/* This function emulates what the windows CRT does to validate file handles */
385int
386_PyVerify_fd(int fd)
387{
Victor Stinner8c62be82010-05-06 00:08:46 +0000388 const int i1 = fd >> IOINFO_L2E;
389 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000390
Antoine Pitrou22e41552010-08-15 18:07:50 +0000391 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000392
Victor Stinner8c62be82010-05-06 00:08:46 +0000393 /* Determine the actual size of the ioinfo structure,
394 * as used by the CRT loaded in memory
395 */
396 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
397 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
398 }
399 if (sizeof_ioinfo == 0) {
400 /* This should not happen... */
401 goto fail;
402 }
403
404 /* See that it isn't a special CLEAR fileno */
405 if (fd != _NO_CONSOLE_FILENO) {
406 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
407 * we check pointer validity and other info
408 */
409 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
410 /* finally, check that the file is open */
411 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
412 if (info->osfile & FOPEN) {
413 return 1;
414 }
415 }
416 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000417 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000418 errno = EBADF;
419 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000420}
421
422/* the special case of checking dup2. The target fd must be in a sensible range */
423static int
424_PyVerify_fd_dup2(int fd1, int fd2)
425{
Victor Stinner8c62be82010-05-06 00:08:46 +0000426 if (!_PyVerify_fd(fd1))
427 return 0;
428 if (fd2 == _NO_CONSOLE_FILENO)
429 return 0;
430 if ((unsigned)fd2 < _NHANDLE_)
431 return 1;
432 else
433 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000434}
435#else
436/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
437#define _PyVerify_fd_dup2(A, B) (1)
438#endif
439
Brian Curtinf5e76d02010-11-24 13:14:05 +0000440/* The following structure was copied from
441 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
442 include doesn't seem to be present in the Windows SDK (at least as included
443 with Visual Studio Express). */
444typedef struct _REPARSE_DATA_BUFFER {
445 ULONG ReparseTag;
446 USHORT ReparseDataLength;
447 USHORT Reserved;
448 union {
449 struct {
450 USHORT SubstituteNameOffset;
451 USHORT SubstituteNameLength;
452 USHORT PrintNameOffset;
453 USHORT PrintNameLength;
454 ULONG Flags;
455 WCHAR PathBuffer[1];
456 } SymbolicLinkReparseBuffer;
457
458 struct {
459 USHORT SubstituteNameOffset;
460 USHORT SubstituteNameLength;
461 USHORT PrintNameOffset;
462 USHORT PrintNameLength;
463 WCHAR PathBuffer[1];
464 } MountPointReparseBuffer;
465
466 struct {
467 UCHAR DataBuffer[1];
468 } GenericReparseBuffer;
469 };
470} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
471
472#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
473 GenericReparseBuffer)
474#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
475
476static int
477_Py_ReadLink(HANDLE reparse_point_handle, ULONG *reparse_tag, wchar_t **target_path)
478{
479 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
480 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
481 DWORD n_bytes_returned;
482 const wchar_t *ptr;
483 wchar_t *buf;
484 size_t len;
485
486 if (0 == DeviceIoControl(
487 reparse_point_handle,
488 FSCTL_GET_REPARSE_POINT,
489 NULL, 0, /* in buffer */
490 target_buffer, sizeof(target_buffer),
491 &n_bytes_returned,
492 NULL)) /* we're not using OVERLAPPED_IO */
493 return 0;
494
495 if (reparse_tag)
496 *reparse_tag = rdb->ReparseTag;
497
498 if (target_path) {
499 switch (rdb->ReparseTag) {
500 case IO_REPARSE_TAG_SYMLINK:
501 /* XXX: Maybe should use SubstituteName? */
502 ptr = rdb->SymbolicLinkReparseBuffer.PathBuffer +
503 rdb->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR);
504 len = rdb->SymbolicLinkReparseBuffer.PrintNameLength/sizeof(WCHAR);
505 break;
506 case IO_REPARSE_TAG_MOUNT_POINT:
507 ptr = rdb->MountPointReparseBuffer.PathBuffer +
508 rdb->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR);
509 len = rdb->MountPointReparseBuffer.SubstituteNameLength/sizeof(WCHAR);
510 break;
511 default:
512 SetLastError(ERROR_REPARSE_TAG_MISMATCH); /* XXX: Proper error code? */
513 return 0;
514 }
515 buf = (wchar_t *)malloc(sizeof(wchar_t)*(len+1));
516 if (!buf) {
517 SetLastError(ERROR_OUTOFMEMORY);
518 return 0;
519 }
520 wcsncpy(buf, ptr, len);
521 buf[len] = L'\0';
522 if (wcsncmp(buf, L"\\??\\", 4) == 0)
523 buf[1] = L'\\';
524 *target_path = buf;
525 }
526
527 return 1;
528}
529
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000530/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000531#ifdef WITH_NEXT_FRAMEWORK
532/* On Darwin/MacOSX a shared library or framework has no access to
533** environ directly, we must obtain it with _NSGetEnviron().
534*/
535#include <crt_externs.h>
536static char **environ;
537#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000538extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000539#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000540
Barry Warsaw53699e91996-12-10 23:23:01 +0000541static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000542convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000543{
Victor Stinner8c62be82010-05-06 00:08:46 +0000544 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000545#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000546 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000547#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000548 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000549#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000550#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000551 APIRET rc;
552 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
553#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000554
Victor Stinner8c62be82010-05-06 00:08:46 +0000555 d = PyDict_New();
556 if (d == NULL)
557 return NULL;
558#ifdef WITH_NEXT_FRAMEWORK
559 if (environ == NULL)
560 environ = *_NSGetEnviron();
561#endif
562#ifdef MS_WINDOWS
563 /* _wenviron must be initialized in this way if the program is started
564 through main() instead of wmain(). */
565 _wgetenv(L"");
566 if (_wenviron == NULL)
567 return d;
568 /* This part ignores errors */
569 for (e = _wenviron; *e != NULL; e++) {
570 PyObject *k;
571 PyObject *v;
572 wchar_t *p = wcschr(*e, L'=');
573 if (p == NULL)
574 continue;
575 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
576 if (k == NULL) {
577 PyErr_Clear();
578 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000579 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000580 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
581 if (v == NULL) {
582 PyErr_Clear();
583 Py_DECREF(k);
584 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000585 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000586 if (PyDict_GetItem(d, k) == NULL) {
587 if (PyDict_SetItem(d, k, v) != 0)
588 PyErr_Clear();
589 }
590 Py_DECREF(k);
591 Py_DECREF(v);
592 }
593#else
594 if (environ == NULL)
595 return d;
596 /* This part ignores errors */
597 for (e = environ; *e != NULL; e++) {
598 PyObject *k;
599 PyObject *v;
600 char *p = strchr(*e, '=');
601 if (p == NULL)
602 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000603 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000604 if (k == NULL) {
605 PyErr_Clear();
606 continue;
607 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000608 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000609 if (v == NULL) {
610 PyErr_Clear();
611 Py_DECREF(k);
612 continue;
613 }
614 if (PyDict_GetItem(d, k) == NULL) {
615 if (PyDict_SetItem(d, k, v) != 0)
616 PyErr_Clear();
617 }
618 Py_DECREF(k);
619 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000620 }
621#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000622#if defined(PYOS_OS2)
623 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
624 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
625 PyObject *v = PyBytes_FromString(buffer);
626 PyDict_SetItemString(d, "BEGINLIBPATH", v);
627 Py_DECREF(v);
628 }
629 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
630 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
631 PyObject *v = PyBytes_FromString(buffer);
632 PyDict_SetItemString(d, "ENDLIBPATH", v);
633 Py_DECREF(v);
634 }
635#endif
636 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000637}
638
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000639/* Set a POSIX-specific error from errno, and return NULL */
640
Barry Warsawd58d7641998-07-23 16:14:40 +0000641static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000642posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000643{
Victor Stinner8c62be82010-05-06 00:08:46 +0000644 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000645}
Barry Warsawd58d7641998-07-23 16:14:40 +0000646static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000647posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000648{
Victor Stinner8c62be82010-05-06 00:08:46 +0000649 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000650}
651
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000652
Mark Hammondef8b6542001-05-13 08:04:26 +0000653static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000654posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000655{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000656 PyObject *name_str, *rc;
657 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
658 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000659 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000660 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
661 name_str);
662 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000663 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000664}
665
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000666#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000667static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000668win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000669{
Victor Stinner8c62be82010-05-06 00:08:46 +0000670 /* XXX We should pass the function name along in the future.
671 (winreg.c also wants to pass the function name.)
672 This would however require an additional param to the
673 Windows error object, which is non-trivial.
674 */
675 errno = GetLastError();
676 if (filename)
677 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
678 else
679 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000680}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000681
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000682static PyObject *
683win32_error_unicode(char* function, Py_UNICODE* filename)
684{
Victor Stinner8c62be82010-05-06 00:08:46 +0000685 /* XXX - see win32_error for comments on 'function' */
686 errno = GetLastError();
687 if (filename)
688 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
689 else
690 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000691}
692
Thomas Wouters477c8d52006-05-27 19:21:47 +0000693static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000694convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000695{
Victor Stinner8c62be82010-05-06 00:08:46 +0000696 if (PyUnicode_CheckExact(*param))
697 Py_INCREF(*param);
698 else if (PyUnicode_Check(*param))
699 /* For a Unicode subtype that's not a Unicode object,
700 return a true Unicode object with the same data. */
701 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
702 PyUnicode_GET_SIZE(*param));
703 else
704 *param = PyUnicode_FromEncodedObject(*param,
705 Py_FileSystemDefaultEncoding,
706 "strict");
707 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000708}
709
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000710#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000711
Guido van Rossumd48f2521997-12-05 22:19:34 +0000712#if defined(PYOS_OS2)
713/**********************************************************************
714 * Helper Function to Trim and Format OS/2 Messages
715 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000716static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000717os2_formatmsg(char *msgbuf, int msglen, char *reason)
718{
719 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
720
721 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
722 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
723
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000724 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000725 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
726 }
727
728 /* Add Optional Reason Text */
729 if (reason) {
730 strcat(msgbuf, " : ");
731 strcat(msgbuf, reason);
732 }
733}
734
735/**********************************************************************
736 * Decode an OS/2 Operating System Error Code
737 *
738 * A convenience function to lookup an OS/2 error code and return a
739 * text message we can use to raise a Python exception.
740 *
741 * Notes:
742 * The messages for errors returned from the OS/2 kernel reside in
743 * the file OSO001.MSG in the \OS2 directory hierarchy.
744 *
745 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000746static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000747os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
748{
749 APIRET rc;
750 ULONG msglen;
751
752 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
753 Py_BEGIN_ALLOW_THREADS
754 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
755 errorcode, "oso001.msg", &msglen);
756 Py_END_ALLOW_THREADS
757
758 if (rc == NO_ERROR)
759 os2_formatmsg(msgbuf, msglen, reason);
760 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000761 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000762 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000763
764 return msgbuf;
765}
766
767/* Set an OS/2-specific error and return NULL. OS/2 kernel
768 errors are not in a global variable e.g. 'errno' nor are
769 they congruent with posix error numbers. */
770
Victor Stinner8c62be82010-05-06 00:08:46 +0000771static PyObject *
772os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000773{
774 char text[1024];
775 PyObject *v;
776
777 os2_strerror(text, sizeof(text), code, "");
778
779 v = Py_BuildValue("(is)", code, text);
780 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000781 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000782 Py_DECREF(v);
783 }
784 return NULL; /* Signal to Python that an Exception is Pending */
785}
786
787#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000788
789/* POSIX generic methods */
790
Barry Warsaw53699e91996-12-10 23:23:01 +0000791static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000792posix_fildes(PyObject *fdobj, int (*func)(int))
793{
Victor Stinner8c62be82010-05-06 00:08:46 +0000794 int fd;
795 int res;
796 fd = PyObject_AsFileDescriptor(fdobj);
797 if (fd < 0)
798 return NULL;
799 if (!_PyVerify_fd(fd))
800 return posix_error();
801 Py_BEGIN_ALLOW_THREADS
802 res = (*func)(fd);
803 Py_END_ALLOW_THREADS
804 if (res < 0)
805 return posix_error();
806 Py_INCREF(Py_None);
807 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000808}
Guido van Rossum21142a01999-01-08 21:05:37 +0000809
810static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000811posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000812{
Victor Stinner8c62be82010-05-06 00:08:46 +0000813 PyObject *opath1 = NULL;
814 char *path1;
815 int res;
816 if (!PyArg_ParseTuple(args, format,
817 PyUnicode_FSConverter, &opath1))
818 return NULL;
819 path1 = PyBytes_AsString(opath1);
820 Py_BEGIN_ALLOW_THREADS
821 res = (*func)(path1);
822 Py_END_ALLOW_THREADS
823 if (res < 0)
824 return posix_error_with_allocated_filename(opath1);
825 Py_DECREF(opath1);
826 Py_INCREF(Py_None);
827 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000828}
829
Barry Warsaw53699e91996-12-10 23:23:01 +0000830static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000831posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000832 char *format,
833 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000834{
Victor Stinner8c62be82010-05-06 00:08:46 +0000835 PyObject *opath1 = NULL, *opath2 = NULL;
836 char *path1, *path2;
837 int res;
838 if (!PyArg_ParseTuple(args, format,
839 PyUnicode_FSConverter, &opath1,
840 PyUnicode_FSConverter, &opath2)) {
841 return NULL;
842 }
843 path1 = PyBytes_AsString(opath1);
844 path2 = PyBytes_AsString(opath2);
845 Py_BEGIN_ALLOW_THREADS
846 res = (*func)(path1, path2);
847 Py_END_ALLOW_THREADS
848 Py_DECREF(opath1);
849 Py_DECREF(opath2);
850 if (res != 0)
851 /* XXX how to report both path1 and path2??? */
852 return posix_error();
853 Py_INCREF(Py_None);
854 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000855}
856
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000857#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000858static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000859win32_1str(PyObject* args, char* func,
860 char* format, BOOL (__stdcall *funcA)(LPCSTR),
861 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000862{
Victor Stinner8c62be82010-05-06 00:08:46 +0000863 PyObject *uni;
864 char *ansi;
865 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000866
Victor Stinner8c62be82010-05-06 00:08:46 +0000867 if (!PyArg_ParseTuple(args, wformat, &uni))
868 PyErr_Clear();
869 else {
870 Py_BEGIN_ALLOW_THREADS
871 result = funcW(PyUnicode_AsUnicode(uni));
872 Py_END_ALLOW_THREADS
873 if (!result)
874 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
875 Py_INCREF(Py_None);
876 return Py_None;
877 }
878 if (!PyArg_ParseTuple(args, format, &ansi))
879 return NULL;
880 Py_BEGIN_ALLOW_THREADS
881 result = funcA(ansi);
882 Py_END_ALLOW_THREADS
883 if (!result)
884 return win32_error(func, ansi);
885 Py_INCREF(Py_None);
886 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000887
888}
889
890/* This is a reimplementation of the C library's chdir function,
891 but one that produces Win32 errors instead of DOS error codes.
892 chdir is essentially a wrapper around SetCurrentDirectory; however,
893 it also needs to set "magic" environment variables indicating
894 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000895static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000896win32_chdir(LPCSTR path)
897{
Victor Stinner8c62be82010-05-06 00:08:46 +0000898 char new_path[MAX_PATH+1];
899 int result;
900 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000901
Victor Stinner8c62be82010-05-06 00:08:46 +0000902 if(!SetCurrentDirectoryA(path))
903 return FALSE;
904 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
905 if (!result)
906 return FALSE;
907 /* In the ANSI API, there should not be any paths longer
908 than MAX_PATH. */
909 assert(result <= MAX_PATH+1);
910 if (strncmp(new_path, "\\\\", 2) == 0 ||
911 strncmp(new_path, "//", 2) == 0)
912 /* UNC path, nothing to do. */
913 return TRUE;
914 env[1] = new_path[0];
915 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000916}
917
918/* The Unicode version differs from the ANSI version
919 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000920static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000921win32_wchdir(LPCWSTR path)
922{
Victor Stinner8c62be82010-05-06 00:08:46 +0000923 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
924 int result;
925 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000926
Victor Stinner8c62be82010-05-06 00:08:46 +0000927 if(!SetCurrentDirectoryW(path))
928 return FALSE;
929 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
930 if (!result)
931 return FALSE;
932 if (result > MAX_PATH+1) {
933 new_path = malloc(result * sizeof(wchar_t));
934 if (!new_path) {
935 SetLastError(ERROR_OUTOFMEMORY);
936 return FALSE;
937 }
938 result = GetCurrentDirectoryW(result, new_path);
939 if (!result) {
940 free(new_path);
941 return FALSE;
942 }
943 }
944 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
945 wcsncmp(new_path, L"//", 2) == 0)
946 /* UNC path, nothing to do. */
947 return TRUE;
948 env[1] = new_path[0];
949 result = SetEnvironmentVariableW(env, new_path);
950 if (new_path != _new_path)
951 free(new_path);
952 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000953}
954#endif
955
Martin v. Löwis14694662006-02-03 12:54:16 +0000956#ifdef MS_WINDOWS
957/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
958 - time stamps are restricted to second resolution
959 - file modification times suffer from forth-and-back conversions between
960 UTC and local time
961 Therefore, we implement our own stat, based on the Win32 API directly.
962*/
Victor Stinner8c62be82010-05-06 00:08:46 +0000963#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000964
965struct win32_stat{
966 int st_dev;
967 __int64 st_ino;
968 unsigned short st_mode;
969 int st_nlink;
970 int st_uid;
971 int st_gid;
972 int st_rdev;
973 __int64 st_size;
974 int st_atime;
975 int st_atime_nsec;
976 int st_mtime;
977 int st_mtime_nsec;
978 int st_ctime;
979 int st_ctime_nsec;
980};
981
982static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
983
984static void
985FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
986{
Victor Stinner8c62be82010-05-06 00:08:46 +0000987 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
988 /* Cannot simply cast and dereference in_ptr,
989 since it might not be aligned properly */
990 __int64 in;
991 memcpy(&in, in_ptr, sizeof(in));
992 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
993 /* XXX Win32 supports time stamps past 2038; we currently don't */
994 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
Martin v. Löwis14694662006-02-03 12:54:16 +0000995}
996
Thomas Wouters477c8d52006-05-27 19:21:47 +0000997static void
998time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
999{
Victor Stinner8c62be82010-05-06 00:08:46 +00001000 /* XXX endianness */
1001 __int64 out;
1002 out = time_in + secs_between_epochs;
1003 out = out * 10000000 + nsec_in / 100;
1004 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001005}
1006
Martin v. Löwis14694662006-02-03 12:54:16 +00001007/* Below, we *know* that ugo+r is 0444 */
1008#if _S_IREAD != 0400
1009#error Unsupported C library
1010#endif
1011static int
1012attributes_to_mode(DWORD attr)
1013{
Victor Stinner8c62be82010-05-06 00:08:46 +00001014 int m = 0;
1015 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1016 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1017 else
1018 m |= _S_IFREG;
1019 if (attr & FILE_ATTRIBUTE_READONLY)
1020 m |= 0444;
1021 else
1022 m |= 0666;
1023 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001024}
1025
1026static int
Brian Curtinf5e76d02010-11-24 13:14:05 +00001027attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001028{
Victor Stinner8c62be82010-05-06 00:08:46 +00001029 memset(result, 0, sizeof(*result));
1030 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1031 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1032 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1033 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1034 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001035 result->st_nlink = info->nNumberOfLinks;
Martin v. Löwis14694662006-02-03 12:54:16 +00001036
Victor Stinner8c62be82010-05-06 00:08:46 +00001037 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001038}
1039
Guido van Rossumd8faa362007-04-27 19:54:29 +00001040static BOOL
Brian Curtinf5e76d02010-11-24 13:14:05 +00001041attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001042{
Victor Stinner8c62be82010-05-06 00:08:46 +00001043 HANDLE hFindFile;
1044 WIN32_FIND_DATAA FileData;
1045 hFindFile = FindFirstFileA(pszFile, &FileData);
1046 if (hFindFile == INVALID_HANDLE_VALUE)
1047 return FALSE;
1048 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001049 memset(info, 0, sizeof(*info));
1050 info->dwFileAttributes = FileData.dwFileAttributes;
1051 info->ftCreationTime = FileData.ftCreationTime;
1052 info->ftLastAccessTime = FileData.ftLastAccessTime;
1053 info->ftLastWriteTime = FileData.ftLastWriteTime;
1054 info->nFileSizeHigh = FileData.nFileSizeHigh;
1055 info->nFileSizeLow = FileData.nFileSizeLow;
1056/* info->nNumberOfLinks = 1; */
Victor Stinner8c62be82010-05-06 00:08:46 +00001057 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001058}
1059
1060static BOOL
Brian Curtinf5e76d02010-11-24 13:14:05 +00001061attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001062{
Victor Stinner8c62be82010-05-06 00:08:46 +00001063 HANDLE hFindFile;
1064 WIN32_FIND_DATAW FileData;
1065 hFindFile = FindFirstFileW(pszFile, &FileData);
1066 if (hFindFile == INVALID_HANDLE_VALUE)
1067 return FALSE;
1068 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001069 memset(info, 0, sizeof(*info));
1070 info->dwFileAttributes = FileData.dwFileAttributes;
1071 info->ftCreationTime = FileData.ftCreationTime;
1072 info->ftLastAccessTime = FileData.ftLastAccessTime;
1073 info->ftLastWriteTime = FileData.ftLastWriteTime;
1074 info->nFileSizeHigh = FileData.nFileSizeHigh;
1075 info->nFileSizeLow = FileData.nFileSizeLow;
1076/* info->nNumberOfLinks = 1; */
Victor Stinner8c62be82010-05-06 00:08:46 +00001077 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001078}
1079
Brian Curtinf5e76d02010-11-24 13:14:05 +00001080#ifndef SYMLOOP_MAX
1081#define SYMLOOP_MAX ( 88 )
1082#endif
1083
1084static int
1085win32_xstat_for_handle(HANDLE hFile, struct win32_stat *result, BOOL traverse, int depth);
1086
1087static int
1088win32_xstat(const char *path, struct win32_stat *result, BOOL traverse, int depth)
1089{
1090 int code;
1091 HANDLE hFile;
1092 BY_HANDLE_FILE_INFORMATION info;
1093 const char *dot;
1094
1095 hFile = CreateFileA(
1096 path,
1097 0, /* desired access */
1098 0, /* share mode */
1099 NULL, /* security attributes */
1100 OPEN_EXISTING,
1101 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1102 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT,
1103 NULL);
1104
1105 if(hFile == INVALID_HANDLE_VALUE) {
1106 /* Either the target doesn't exist, or we don't have access to
1107 get a handle to it. If the former, we need to return an error.
1108 If the latter, we can use attributes_from_dir. */
1109 if (GetLastError() != ERROR_SHARING_VIOLATION)
1110 goto err;
1111 else {
1112 /* Could not get attributes on open file. Fall back to
1113 reading the directory. */
1114 if (!attributes_from_dir(path, &info))
1115 /* Very strange. This should not fail now */
1116 goto err;
1117 if (traverse && (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
1118 /* Should traverse, but cannot open reparse point handle */
1119 SetLastError(ERROR_SHARING_VIOLATION);
1120 goto err;
1121 }
1122 attribute_data_to_stat(&info, result);
1123 }
1124 }
1125 else {
1126 code = win32_xstat_for_handle(hFile, result, traverse, depth);
1127 CloseHandle(hFile);
1128 if (code != 0)
1129 return code;
1130 }
1131
1132 /* Set S_IEXEC if it is an .exe, .bat, ... */
1133 dot = strrchr(path, '.');
1134 if (dot) {
1135 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1136 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1137 result->st_mode |= 0111;
1138 }
1139 return 0;
1140
1141err:
1142 /* Protocol violation: we explicitly clear errno, instead of
1143 setting it to a POSIX error. Callers should use GetLastError. */
1144 errno = 0;
1145 return -1;
1146}
1147
1148static int
1149win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth)
1150{
1151 int code;
1152 HANDLE hFile;
1153 BY_HANDLE_FILE_INFORMATION info;
1154 const wchar_t *dot;
1155
1156 hFile = CreateFileW(
1157 path,
1158 0, /* desired access */
1159 0, /* share mode */
1160 NULL, /* security attributes */
1161 OPEN_EXISTING,
1162 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1163 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT,
1164 NULL);
1165
1166 if(hFile == INVALID_HANDLE_VALUE) {
1167 /* Either the target doesn't exist, or we don't have access to
1168 get a handle to it. If the former, we need to return an error.
1169 If the latter, we can use attributes_from_dir. */
1170 if (GetLastError() != ERROR_SHARING_VIOLATION)
1171 goto err;
1172 else {
1173 /* Could not get attributes on open file. Fall back to
1174 reading the directory. */
1175 if (!attributes_from_dir_w(path, &info))
1176 /* Very strange. This should not fail now */
1177 goto err;
1178 if (traverse && (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
1179 /* Should traverse, but cannot open reparse point handle */
1180 SetLastError(ERROR_SHARING_VIOLATION);
1181 goto err;
1182 }
1183 attribute_data_to_stat(&info, result);
1184 }
1185 }
1186 else {
1187 code = win32_xstat_for_handle(hFile, result, traverse, depth);
1188 CloseHandle(hFile);
1189 if (code != 0)
1190 return code;
1191 }
1192
1193 /* Set S_IEXEC if it is an .exe, .bat, ... */
1194 dot = wcsrchr(path, '.');
1195 if (dot) {
1196 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1197 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1198 result->st_mode |= 0111;
1199 }
1200 return 0;
1201
1202err:
1203 /* Protocol violation: we explicitly clear errno, instead of
1204 setting it to a POSIX error. Callers should use GetLastError. */
1205 errno = 0;
1206 return -1;
1207}
1208
1209static int
1210win32_xstat_for_handle(HANDLE hFile, struct win32_stat *result, BOOL traverse, int depth)
1211{
1212 int code;
1213 BOOL reparse_tag;
1214 wchar_t *target_path;
1215 BY_HANDLE_FILE_INFORMATION info;
1216
1217 if (!GetFileInformationByHandle(hFile, &info))
1218 return -1;
1219
1220 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1221 if (traverse) {
1222 if (depth + 1 > SYMLOOP_MAX) {
1223 SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */
1224 return -1;
1225 }
1226 if (!_Py_ReadLink(hFile, NULL, &target_path))
1227 return -1;
1228 code = win32_xstat_w(target_path, result, traverse, depth + 1);
1229 free(target_path);
1230 return code;
1231 } else {
1232 if (!_Py_ReadLink(hFile, &reparse_tag, NULL))
1233 return -1;
1234 attribute_data_to_stat(&info, result);
1235 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
1236 /* first clear the S_IFMT bits */
1237 result->st_mode ^= (result->st_mode & 0170000);
1238 /* now set the bits that make this a symlink */
1239 result->st_mode |= 0120000;
1240 }
1241 }
1242 } else {
1243 attribute_data_to_stat(&info, result);
1244 }
1245 return 0;
1246}
1247
Brian Curtind40e6f72010-07-08 21:39:08 +00001248/* About the following functions: win32_lstat, win32_lstat_w, win32_stat,
1249 win32_stat_w
1250
1251 In Posix, stat automatically traverses symlinks and returns the stat
1252 structure for the target. In Windows, the equivalent GetFileAttributes by
1253 default does not traverse symlinks and instead returns attributes for
1254 the symlink.
1255
1256 Therefore, win32_lstat will get the attributes traditionally, and
1257 win32_stat will first explicitly resolve the symlink target and then will
1258 call win32_lstat on that result.
1259
1260 The _w represent Unicode equivalents of the aformentioned ANSI functions. */
1261
1262static int
1263win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001264{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001265 return win32_xstat(path, result, FALSE, 0);
Martin v. Löwis14694662006-02-03 12:54:16 +00001266}
1267
Victor Stinner8c62be82010-05-06 00:08:46 +00001268static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001269win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001270{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001271 return win32_xstat_w(path, result, FALSE, 0);
Brian Curtind40e6f72010-07-08 21:39:08 +00001272}
1273
1274static int
1275win32_stat(const char* path, struct win32_stat *result)
1276{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001277 return win32_xstat(path, result, TRUE, 0);
Brian Curtind40e6f72010-07-08 21:39:08 +00001278}
1279
1280static int
1281win32_stat_w(const wchar_t* path, struct win32_stat *result)
1282{
Brian Curtinf5e76d02010-11-24 13:14:05 +00001283 return win32_xstat_w(path, result, TRUE, 0);
Martin v. Löwis14694662006-02-03 12:54:16 +00001284}
1285
1286static int
1287win32_fstat(int file_number, struct win32_stat *result)
1288{
Victor Stinner8c62be82010-05-06 00:08:46 +00001289 BY_HANDLE_FILE_INFORMATION info;
1290 HANDLE h;
1291 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001292
Victor Stinner8c62be82010-05-06 00:08:46 +00001293 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001294
Victor Stinner8c62be82010-05-06 00:08:46 +00001295 /* Protocol violation: we explicitly clear errno, instead of
1296 setting it to a POSIX error. Callers should use GetLastError. */
1297 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001298
Victor Stinner8c62be82010-05-06 00:08:46 +00001299 if (h == INVALID_HANDLE_VALUE) {
1300 /* This is really a C library error (invalid file handle).
1301 We set the Win32 error to the closes one matching. */
1302 SetLastError(ERROR_INVALID_HANDLE);
1303 return -1;
1304 }
1305 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001306
Victor Stinner8c62be82010-05-06 00:08:46 +00001307 type = GetFileType(h);
1308 if (type == FILE_TYPE_UNKNOWN) {
1309 DWORD error = GetLastError();
1310 if (error != 0) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001311 return -1;
Victor Stinner8c62be82010-05-06 00:08:46 +00001312 }
1313 /* else: valid but unknown file */
1314 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001315
Victor Stinner8c62be82010-05-06 00:08:46 +00001316 if (type != FILE_TYPE_DISK) {
1317 if (type == FILE_TYPE_CHAR)
1318 result->st_mode = _S_IFCHR;
1319 else if (type == FILE_TYPE_PIPE)
1320 result->st_mode = _S_IFIFO;
1321 return 0;
1322 }
1323
1324 if (!GetFileInformationByHandle(h, &info)) {
1325 return -1;
1326 }
1327
Brian Curtinf5e76d02010-11-24 13:14:05 +00001328 attribute_data_to_stat(&info, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001329 /* specific to fstat() */
Victor Stinner8c62be82010-05-06 00:08:46 +00001330 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1331 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001332}
1333
1334#endif /* MS_WINDOWS */
1335
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001336PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001337"stat_result: Result from stat or lstat.\n\n\
1338This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001339 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001340or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1341\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001342Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1343or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001344\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001345See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001346
1347static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001348 {"st_mode", "protection bits"},
1349 {"st_ino", "inode"},
1350 {"st_dev", "device"},
1351 {"st_nlink", "number of hard links"},
1352 {"st_uid", "user ID of owner"},
1353 {"st_gid", "group ID of owner"},
1354 {"st_size", "total size, in bytes"},
1355 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1356 {NULL, "integer time of last access"},
1357 {NULL, "integer time of last modification"},
1358 {NULL, "integer time of last change"},
1359 {"st_atime", "time of last access"},
1360 {"st_mtime", "time of last modification"},
1361 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001362#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001363 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001364#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001365#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001367#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001368#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001369 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001370#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001371#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001372 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001373#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001374#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001375 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001376#endif
1377#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001378 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001379#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001380 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001381};
1382
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001383#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001384#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001385#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001386#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001387#endif
1388
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001389#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001390#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1391#else
1392#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1393#endif
1394
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001395#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001396#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1397#else
1398#define ST_RDEV_IDX ST_BLOCKS_IDX
1399#endif
1400
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001401#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1402#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1403#else
1404#define ST_FLAGS_IDX ST_RDEV_IDX
1405#endif
1406
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001407#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001408#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001409#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001410#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001411#endif
1412
1413#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1414#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1415#else
1416#define ST_BIRTHTIME_IDX ST_GEN_IDX
1417#endif
1418
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001419static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001420 "stat_result", /* name */
1421 stat_result__doc__, /* doc */
1422 stat_result_fields,
1423 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001424};
1425
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001426PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001427"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1428This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001429 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001430or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001431\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001432See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001433
1434static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001435 {"f_bsize", },
1436 {"f_frsize", },
1437 {"f_blocks", },
1438 {"f_bfree", },
1439 {"f_bavail", },
1440 {"f_files", },
1441 {"f_ffree", },
1442 {"f_favail", },
1443 {"f_flag", },
1444 {"f_namemax",},
1445 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001446};
1447
1448static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001449 "statvfs_result", /* name */
1450 statvfs_result__doc__, /* doc */
1451 statvfs_result_fields,
1452 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001453};
1454
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001455static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001456static PyTypeObject StatResultType;
1457static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001458static newfunc structseq_new;
1459
1460static PyObject *
1461statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1462{
Victor Stinner8c62be82010-05-06 00:08:46 +00001463 PyStructSequence *result;
1464 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001465
Victor Stinner8c62be82010-05-06 00:08:46 +00001466 result = (PyStructSequence*)structseq_new(type, args, kwds);
1467 if (!result)
1468 return NULL;
1469 /* If we have been initialized from a tuple,
1470 st_?time might be set to None. Initialize it
1471 from the int slots. */
1472 for (i = 7; i <= 9; i++) {
1473 if (result->ob_item[i+3] == Py_None) {
1474 Py_DECREF(Py_None);
1475 Py_INCREF(result->ob_item[i]);
1476 result->ob_item[i+3] = result->ob_item[i];
1477 }
1478 }
1479 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001480}
1481
1482
1483
1484/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001485static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001486
1487PyDoc_STRVAR(stat_float_times__doc__,
1488"stat_float_times([newval]) -> oldval\n\n\
1489Determine whether os.[lf]stat represents time stamps as float objects.\n\
1490If newval is True, future calls to stat() return floats, if it is False,\n\
1491future calls return ints. \n\
1492If newval is omitted, return the current setting.\n");
1493
1494static PyObject*
1495stat_float_times(PyObject* self, PyObject *args)
1496{
Victor Stinner8c62be82010-05-06 00:08:46 +00001497 int newval = -1;
1498 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1499 return NULL;
1500 if (newval == -1)
1501 /* Return old value */
1502 return PyBool_FromLong(_stat_float_times);
1503 _stat_float_times = newval;
1504 Py_INCREF(Py_None);
1505 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001506}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001507
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001508static void
1509fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1510{
Victor Stinner8c62be82010-05-06 00:08:46 +00001511 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001512#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001513 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001514#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001515 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001516#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001517 if (!ival)
1518 return;
1519 if (_stat_float_times) {
1520 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1521 } else {
1522 fval = ival;
1523 Py_INCREF(fval);
1524 }
1525 PyStructSequence_SET_ITEM(v, index, ival);
1526 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001527}
1528
Tim Peters5aa91602002-01-30 05:46:57 +00001529/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001530 (used by posix_stat() and posix_fstat()) */
1531static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001532_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001533{
Victor Stinner8c62be82010-05-06 00:08:46 +00001534 unsigned long ansec, mnsec, cnsec;
1535 PyObject *v = PyStructSequence_New(&StatResultType);
1536 if (v == NULL)
1537 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001538
Victor Stinner8c62be82010-05-06 00:08:46 +00001539 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001540#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001541 PyStructSequence_SET_ITEM(v, 1,
1542 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001543#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001544 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001545#endif
1546#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001547 PyStructSequence_SET_ITEM(v, 2,
1548 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001549#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001550 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001551#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001552 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1553 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1554 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001555#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001556 PyStructSequence_SET_ITEM(v, 6,
1557 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001558#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001559 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001560#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001561
Martin v. Löwis14694662006-02-03 12:54:16 +00001562#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001563 ansec = st->st_atim.tv_nsec;
1564 mnsec = st->st_mtim.tv_nsec;
1565 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001566#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001567 ansec = st->st_atimespec.tv_nsec;
1568 mnsec = st->st_mtimespec.tv_nsec;
1569 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001570#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001571 ansec = st->st_atime_nsec;
1572 mnsec = st->st_mtime_nsec;
1573 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001574#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001575 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001576#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001577 fill_time(v, 7, st->st_atime, ansec);
1578 fill_time(v, 8, st->st_mtime, mnsec);
1579 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001580
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001581#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001582 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1583 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001584#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001585#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001586 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1587 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001588#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001589#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001590 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1591 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001592#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001593#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001594 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1595 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001596#endif
1597#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001598 {
1599 PyObject *val;
1600 unsigned long bsec,bnsec;
1601 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001602#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001603 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001604#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001605 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001606#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001607 if (_stat_float_times) {
1608 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1609 } else {
1610 val = PyLong_FromLong((long)bsec);
1611 }
1612 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1613 val);
1614 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001615#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001616#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001617 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1618 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001619#endif
Fred Drake699f3522000-06-29 21:12:41 +00001620
Victor Stinner8c62be82010-05-06 00:08:46 +00001621 if (PyErr_Occurred()) {
1622 Py_DECREF(v);
1623 return NULL;
1624 }
Fred Drake699f3522000-06-29 21:12:41 +00001625
Victor Stinner8c62be82010-05-06 00:08:46 +00001626 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001627}
1628
Barry Warsaw53699e91996-12-10 23:23:01 +00001629static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001630posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001631 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001632#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001633 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001634#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001635 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001636#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001637 char *wformat,
1638 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001639{
Victor Stinner8c62be82010-05-06 00:08:46 +00001640 STRUCT_STAT st;
1641 PyObject *opath;
1642 char *path;
1643 int res;
1644 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001645
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001646#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001647 PyUnicodeObject *po;
1648 if (PyArg_ParseTuple(args, wformat, &po)) {
1649 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001650
Victor Stinner8c62be82010-05-06 00:08:46 +00001651 Py_BEGIN_ALLOW_THREADS
1652 /* PyUnicode_AS_UNICODE result OK without
1653 thread lock as it is a simple dereference. */
1654 res = wstatfunc(wpath, &st);
1655 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001656
Victor Stinner8c62be82010-05-06 00:08:46 +00001657 if (res != 0)
1658 return win32_error_unicode("stat", wpath);
1659 return _pystat_fromstructstat(&st);
1660 }
1661 /* Drop the argument parsing error as narrow strings
1662 are also valid. */
1663 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001664#endif
1665
Victor Stinner8c62be82010-05-06 00:08:46 +00001666 if (!PyArg_ParseTuple(args, format,
1667 PyUnicode_FSConverter, &opath))
1668 return NULL;
1669 path = PyBytes_AsString(opath);
1670 Py_BEGIN_ALLOW_THREADS
1671 res = (*statfunc)(path, &st);
1672 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001673
Victor Stinner8c62be82010-05-06 00:08:46 +00001674 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001675#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001676 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001677#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001678 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001679#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001680 }
1681 else
1682 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001683
Victor Stinner8c62be82010-05-06 00:08:46 +00001684 Py_DECREF(opath);
1685 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001686}
1687
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001688/* POSIX methods */
1689
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001690PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001691"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001692Use the real uid/gid to test for access to a path. Note that most\n\
1693operations will use the effective uid/gid, therefore this routine can\n\
1694be used in a suid/sgid environment to test if the invoking user has the\n\
1695specified access to the path. The mode argument can be F_OK to test\n\
1696existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001697
1698static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001699posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001700{
Victor Stinner8c62be82010-05-06 00:08:46 +00001701 PyObject *opath;
1702 char *path;
1703 int mode;
1704
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001705#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001706 DWORD attr;
1707 PyUnicodeObject *po;
1708 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1709 Py_BEGIN_ALLOW_THREADS
1710 /* PyUnicode_AS_UNICODE OK without thread lock as
1711 it is a simple dereference. */
1712 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1713 Py_END_ALLOW_THREADS
1714 goto finish;
1715 }
1716 /* Drop the argument parsing error as narrow strings
1717 are also valid. */
1718 PyErr_Clear();
1719 if (!PyArg_ParseTuple(args, "O&i:access",
1720 PyUnicode_FSConverter, &opath, &mode))
1721 return NULL;
1722 path = PyBytes_AsString(opath);
1723 Py_BEGIN_ALLOW_THREADS
1724 attr = GetFileAttributesA(path);
1725 Py_END_ALLOW_THREADS
1726 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001727finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001728 if (attr == 0xFFFFFFFF)
1729 /* File does not exist, or cannot read attributes */
1730 return PyBool_FromLong(0);
1731 /* Access is possible if either write access wasn't requested, or
1732 the file isn't read-only, or if it's a directory, as there are
1733 no read-only directories on Windows. */
1734 return PyBool_FromLong(!(mode & 2)
1735 || !(attr & FILE_ATTRIBUTE_READONLY)
1736 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001737#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001738 int res;
1739 if (!PyArg_ParseTuple(args, "O&i:access",
1740 PyUnicode_FSConverter, &opath, &mode))
1741 return NULL;
1742 path = PyBytes_AsString(opath);
1743 Py_BEGIN_ALLOW_THREADS
1744 res = access(path, mode);
1745 Py_END_ALLOW_THREADS
1746 Py_DECREF(opath);
1747 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001748#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001749}
1750
Guido van Rossumd371ff11999-01-25 16:12:23 +00001751#ifndef F_OK
1752#define F_OK 0
1753#endif
1754#ifndef R_OK
1755#define R_OK 4
1756#endif
1757#ifndef W_OK
1758#define W_OK 2
1759#endif
1760#ifndef X_OK
1761#define X_OK 1
1762#endif
1763
1764#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001765PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001766"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001767Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001768
1769static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001770posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001771{
Victor Stinner8c62be82010-05-06 00:08:46 +00001772 int id;
1773 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001774
Victor Stinner8c62be82010-05-06 00:08:46 +00001775 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1776 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001777
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001778#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001779 /* file descriptor 0 only, the default input device (stdin) */
1780 if (id == 0) {
1781 ret = ttyname();
1782 }
1783 else {
1784 ret = NULL;
1785 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001786#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001787 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001788#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001789 if (ret == NULL)
1790 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001791 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001792}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001793#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001794
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001795#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001796PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001797"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001798Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001799
1800static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001801posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001802{
Victor Stinner8c62be82010-05-06 00:08:46 +00001803 char *ret;
1804 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001805
Greg Wardb48bc172000-03-01 21:51:56 +00001806#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001807 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001808#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001809 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001810#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001811 if (ret == NULL)
1812 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001813 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001814}
1815#endif
1816
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001817PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001818"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001819Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001820
Barry Warsaw53699e91996-12-10 23:23:01 +00001821static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001822posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001823{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001824#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001825 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001826#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001827 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001828#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001829 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001830#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001831 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001832#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001833}
1834
Fred Drake4d1e64b2002-04-15 19:40:07 +00001835#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001836PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001837"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001838Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001839opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001840
1841static PyObject *
1842posix_fchdir(PyObject *self, PyObject *fdobj)
1843{
Victor Stinner8c62be82010-05-06 00:08:46 +00001844 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001845}
1846#endif /* HAVE_FCHDIR */
1847
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001848
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001849PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001850"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001851Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001852
Barry Warsaw53699e91996-12-10 23:23:01 +00001853static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001854posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001855{
Victor Stinner8c62be82010-05-06 00:08:46 +00001856 PyObject *opath = NULL;
1857 char *path = NULL;
1858 int i;
1859 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001860#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001861 DWORD attr;
1862 PyUnicodeObject *po;
1863 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1864 Py_BEGIN_ALLOW_THREADS
1865 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1866 if (attr != 0xFFFFFFFF) {
1867 if (i & _S_IWRITE)
1868 attr &= ~FILE_ATTRIBUTE_READONLY;
1869 else
1870 attr |= FILE_ATTRIBUTE_READONLY;
1871 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1872 }
1873 else
1874 res = 0;
1875 Py_END_ALLOW_THREADS
1876 if (!res)
1877 return win32_error_unicode("chmod",
1878 PyUnicode_AS_UNICODE(po));
1879 Py_INCREF(Py_None);
1880 return Py_None;
1881 }
1882 /* Drop the argument parsing error as narrow strings
1883 are also valid. */
1884 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001885
Victor Stinner8c62be82010-05-06 00:08:46 +00001886 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1887 &opath, &i))
1888 return NULL;
1889 path = PyBytes_AsString(opath);
1890 Py_BEGIN_ALLOW_THREADS
1891 attr = GetFileAttributesA(path);
1892 if (attr != 0xFFFFFFFF) {
1893 if (i & _S_IWRITE)
1894 attr &= ~FILE_ATTRIBUTE_READONLY;
1895 else
1896 attr |= FILE_ATTRIBUTE_READONLY;
1897 res = SetFileAttributesA(path, attr);
1898 }
1899 else
1900 res = 0;
1901 Py_END_ALLOW_THREADS
1902 if (!res) {
1903 win32_error("chmod", path);
1904 Py_DECREF(opath);
1905 return NULL;
1906 }
1907 Py_DECREF(opath);
1908 Py_INCREF(Py_None);
1909 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001910#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00001911 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1912 &opath, &i))
1913 return NULL;
1914 path = PyBytes_AsString(opath);
1915 Py_BEGIN_ALLOW_THREADS
1916 res = chmod(path, i);
1917 Py_END_ALLOW_THREADS
1918 if (res < 0)
1919 return posix_error_with_allocated_filename(opath);
1920 Py_DECREF(opath);
1921 Py_INCREF(Py_None);
1922 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001923#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001924}
1925
Christian Heimes4e30a842007-11-30 22:12:06 +00001926#ifdef HAVE_FCHMOD
1927PyDoc_STRVAR(posix_fchmod__doc__,
1928"fchmod(fd, mode)\n\n\
1929Change the access permissions of the file given by file\n\
1930descriptor fd.");
1931
1932static PyObject *
1933posix_fchmod(PyObject *self, PyObject *args)
1934{
Victor Stinner8c62be82010-05-06 00:08:46 +00001935 int fd, mode, res;
1936 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1937 return NULL;
1938 Py_BEGIN_ALLOW_THREADS
1939 res = fchmod(fd, mode);
1940 Py_END_ALLOW_THREADS
1941 if (res < 0)
1942 return posix_error();
1943 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001944}
1945#endif /* HAVE_FCHMOD */
1946
1947#ifdef HAVE_LCHMOD
1948PyDoc_STRVAR(posix_lchmod__doc__,
1949"lchmod(path, mode)\n\n\
1950Change the access permissions of a file. If path is a symlink, this\n\
1951affects the link itself rather than the target.");
1952
1953static PyObject *
1954posix_lchmod(PyObject *self, PyObject *args)
1955{
Victor Stinner8c62be82010-05-06 00:08:46 +00001956 PyObject *opath;
1957 char *path;
1958 int i;
1959 int res;
1960 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
1961 &opath, &i))
1962 return NULL;
1963 path = PyBytes_AsString(opath);
1964 Py_BEGIN_ALLOW_THREADS
1965 res = lchmod(path, i);
1966 Py_END_ALLOW_THREADS
1967 if (res < 0)
1968 return posix_error_with_allocated_filename(opath);
1969 Py_DECREF(opath);
1970 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001971}
1972#endif /* HAVE_LCHMOD */
1973
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001974
Thomas Wouterscf297e42007-02-23 15:07:44 +00001975#ifdef HAVE_CHFLAGS
1976PyDoc_STRVAR(posix_chflags__doc__,
1977"chflags(path, flags)\n\n\
1978Set file flags.");
1979
1980static PyObject *
1981posix_chflags(PyObject *self, PyObject *args)
1982{
Victor Stinner8c62be82010-05-06 00:08:46 +00001983 PyObject *opath;
1984 char *path;
1985 unsigned long flags;
1986 int res;
1987 if (!PyArg_ParseTuple(args, "O&k:chflags",
1988 PyUnicode_FSConverter, &opath, &flags))
1989 return NULL;
1990 path = PyBytes_AsString(opath);
1991 Py_BEGIN_ALLOW_THREADS
1992 res = chflags(path, flags);
1993 Py_END_ALLOW_THREADS
1994 if (res < 0)
1995 return posix_error_with_allocated_filename(opath);
1996 Py_DECREF(opath);
1997 Py_INCREF(Py_None);
1998 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00001999}
2000#endif /* HAVE_CHFLAGS */
2001
2002#ifdef HAVE_LCHFLAGS
2003PyDoc_STRVAR(posix_lchflags__doc__,
2004"lchflags(path, flags)\n\n\
2005Set file flags.\n\
2006This function will not follow symbolic links.");
2007
2008static PyObject *
2009posix_lchflags(PyObject *self, PyObject *args)
2010{
Victor Stinner8c62be82010-05-06 00:08:46 +00002011 PyObject *opath;
2012 char *path;
2013 unsigned long flags;
2014 int res;
2015 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2016 PyUnicode_FSConverter, &opath, &flags))
2017 return NULL;
2018 path = PyBytes_AsString(opath);
2019 Py_BEGIN_ALLOW_THREADS
2020 res = lchflags(path, flags);
2021 Py_END_ALLOW_THREADS
2022 if (res < 0)
2023 return posix_error_with_allocated_filename(opath);
2024 Py_DECREF(opath);
2025 Py_INCREF(Py_None);
2026 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002027}
2028#endif /* HAVE_LCHFLAGS */
2029
Martin v. Löwis244edc82001-10-04 22:44:26 +00002030#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002031PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002032"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002033Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002034
2035static PyObject *
2036posix_chroot(PyObject *self, PyObject *args)
2037{
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002039}
2040#endif
2041
Guido van Rossum21142a01999-01-08 21:05:37 +00002042#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002043PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002044"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002045force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002046
2047static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002048posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002049{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002050 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002051}
2052#endif /* HAVE_FSYNC */
2053
2054#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002055
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002056#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002057extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2058#endif
2059
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002060PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002061"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002062force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002063 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002064
2065static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002066posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002067{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002068 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002069}
2070#endif /* HAVE_FDATASYNC */
2071
2072
Fredrik Lundh10723342000-07-10 16:38:09 +00002073#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002074PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002075"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002076Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002077
Barry Warsaw53699e91996-12-10 23:23:01 +00002078static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002079posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002080{
Victor Stinner8c62be82010-05-06 00:08:46 +00002081 PyObject *opath;
2082 char *path;
2083 long uid, gid;
2084 int res;
2085 if (!PyArg_ParseTuple(args, "O&ll:chown",
2086 PyUnicode_FSConverter, &opath,
2087 &uid, &gid))
2088 return NULL;
2089 path = PyBytes_AsString(opath);
2090 Py_BEGIN_ALLOW_THREADS
2091 res = chown(path, (uid_t) uid, (gid_t) gid);
2092 Py_END_ALLOW_THREADS
2093 if (res < 0)
2094 return posix_error_with_allocated_filename(opath);
2095 Py_DECREF(opath);
2096 Py_INCREF(Py_None);
2097 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002098}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002099#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002100
Christian Heimes4e30a842007-11-30 22:12:06 +00002101#ifdef HAVE_FCHOWN
2102PyDoc_STRVAR(posix_fchown__doc__,
2103"fchown(fd, uid, gid)\n\n\
2104Change the owner and group id of the file given by file descriptor\n\
2105fd to the numeric uid and gid.");
2106
2107static PyObject *
2108posix_fchown(PyObject *self, PyObject *args)
2109{
Victor Stinner8c62be82010-05-06 00:08:46 +00002110 int fd;
2111 long uid, gid;
2112 int res;
2113 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2114 return NULL;
2115 Py_BEGIN_ALLOW_THREADS
2116 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2117 Py_END_ALLOW_THREADS
2118 if (res < 0)
2119 return posix_error();
2120 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002121}
2122#endif /* HAVE_FCHOWN */
2123
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002124#ifdef HAVE_LCHOWN
2125PyDoc_STRVAR(posix_lchown__doc__,
2126"lchown(path, uid, gid)\n\n\
2127Change the owner and group id of path to the numeric uid and gid.\n\
2128This function will not follow symbolic links.");
2129
2130static PyObject *
2131posix_lchown(PyObject *self, PyObject *args)
2132{
Victor Stinner8c62be82010-05-06 00:08:46 +00002133 PyObject *opath;
2134 char *path;
2135 long uid, gid;
2136 int res;
2137 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2138 PyUnicode_FSConverter, &opath,
2139 &uid, &gid))
2140 return NULL;
2141 path = PyBytes_AsString(opath);
2142 Py_BEGIN_ALLOW_THREADS
2143 res = lchown(path, (uid_t) uid, (gid_t) gid);
2144 Py_END_ALLOW_THREADS
2145 if (res < 0)
2146 return posix_error_with_allocated_filename(opath);
2147 Py_DECREF(opath);
2148 Py_INCREF(Py_None);
2149 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002150}
2151#endif /* HAVE_LCHOWN */
2152
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002153
Guido van Rossum36bc6801995-06-14 22:54:23 +00002154#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002155static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002156posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002157{
Victor Stinner8c62be82010-05-06 00:08:46 +00002158 char buf[1026];
2159 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002160
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002161#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002162 if (!use_bytes) {
2163 wchar_t wbuf[1026];
2164 wchar_t *wbuf2 = wbuf;
2165 PyObject *resobj;
2166 DWORD len;
2167 Py_BEGIN_ALLOW_THREADS
2168 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2169 /* If the buffer is large enough, len does not include the
2170 terminating \0. If the buffer is too small, len includes
2171 the space needed for the terminator. */
2172 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2173 wbuf2 = malloc(len * sizeof(wchar_t));
2174 if (wbuf2)
2175 len = GetCurrentDirectoryW(len, wbuf2);
2176 }
2177 Py_END_ALLOW_THREADS
2178 if (!wbuf2) {
2179 PyErr_NoMemory();
2180 return NULL;
2181 }
2182 if (!len) {
2183 if (wbuf2 != wbuf) free(wbuf2);
2184 return win32_error("getcwdu", NULL);
2185 }
2186 resobj = PyUnicode_FromWideChar(wbuf2, len);
2187 if (wbuf2 != wbuf) free(wbuf2);
2188 return resobj;
2189 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002190#endif
2191
Victor Stinner8c62be82010-05-06 00:08:46 +00002192 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002193#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002194 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002195#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002196 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002197#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002198 Py_END_ALLOW_THREADS
2199 if (res == NULL)
2200 return posix_error();
2201 if (use_bytes)
2202 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002203 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002204}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002205
2206PyDoc_STRVAR(posix_getcwd__doc__,
2207"getcwd() -> path\n\n\
2208Return a unicode string representing the current working directory.");
2209
2210static PyObject *
2211posix_getcwd_unicode(PyObject *self)
2212{
2213 return posix_getcwd(0);
2214}
2215
2216PyDoc_STRVAR(posix_getcwdb__doc__,
2217"getcwdb() -> path\n\n\
2218Return a bytes string representing the current working directory.");
2219
2220static PyObject *
2221posix_getcwd_bytes(PyObject *self)
2222{
2223 return posix_getcwd(1);
2224}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002225#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002226
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002227
Guido van Rossumb6775db1994-08-01 11:34:53 +00002228#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002229PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002230"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002231Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002232
Barry Warsaw53699e91996-12-10 23:23:01 +00002233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002234posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002235{
Victor Stinner8c62be82010-05-06 00:08:46 +00002236 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002237}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002238#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002239
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002240
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002241PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002242"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002243Return a list containing the names of the entries in the directory.\n\
2244\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002245 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002246\n\
2247The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002248entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002249
Barry Warsaw53699e91996-12-10 23:23:01 +00002250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002251posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002252{
Victor Stinner8c62be82010-05-06 00:08:46 +00002253 /* XXX Should redo this putting the (now four) versions of opendir
2254 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002255#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002256
Victor Stinner8c62be82010-05-06 00:08:46 +00002257 PyObject *d, *v;
2258 HANDLE hFindFile;
2259 BOOL result;
2260 WIN32_FIND_DATA FileData;
2261 PyObject *opath;
2262 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2263 char *bufptr = namebuf;
2264 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002265
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002266 PyObject *po = NULL;
2267 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002268 WIN32_FIND_DATAW wFileData;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002269 Py_UNICODE *wnamebuf, *po_wchars;
2270
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002271 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002272 po_wchars = L".";
2273 len = 1;
2274 } else {
2275 po_wchars = PyUnicode_AS_UNICODE(po);
2276 len = PyUnicode_GET_SIZE(po);
2277 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002278 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002279 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2280 if (!wnamebuf) {
2281 PyErr_NoMemory();
2282 return NULL;
2283 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002284 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002285 if (len > 0) {
2286 Py_UNICODE wch = wnamebuf[len-1];
2287 if (wch != L'/' && wch != L'\\' && wch != L':')
2288 wnamebuf[len++] = L'\\';
2289 wcscpy(wnamebuf + len, L"*.*");
2290 }
2291 if ((d = PyList_New(0)) == NULL) {
2292 free(wnamebuf);
2293 return NULL;
2294 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002295 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002296 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002297 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002298 if (hFindFile == INVALID_HANDLE_VALUE) {
2299 int error = GetLastError();
2300 if (error == ERROR_FILE_NOT_FOUND) {
2301 free(wnamebuf);
2302 return d;
2303 }
2304 Py_DECREF(d);
2305 win32_error_unicode("FindFirstFileW", wnamebuf);
2306 free(wnamebuf);
2307 return NULL;
2308 }
2309 do {
2310 /* Skip over . and .. */
2311 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2312 wcscmp(wFileData.cFileName, L"..") != 0) {
2313 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2314 if (v == NULL) {
2315 Py_DECREF(d);
2316 d = NULL;
2317 break;
2318 }
2319 if (PyList_Append(d, v) != 0) {
2320 Py_DECREF(v);
2321 Py_DECREF(d);
2322 d = NULL;
2323 break;
2324 }
2325 Py_DECREF(v);
2326 }
2327 Py_BEGIN_ALLOW_THREADS
2328 result = FindNextFileW(hFindFile, &wFileData);
2329 Py_END_ALLOW_THREADS
2330 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2331 it got to the end of the directory. */
2332 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2333 Py_DECREF(d);
2334 win32_error_unicode("FindNextFileW", wnamebuf);
2335 FindClose(hFindFile);
2336 free(wnamebuf);
2337 return NULL;
2338 }
2339 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002340
Victor Stinner8c62be82010-05-06 00:08:46 +00002341 if (FindClose(hFindFile) == FALSE) {
2342 Py_DECREF(d);
2343 win32_error_unicode("FindClose", wnamebuf);
2344 free(wnamebuf);
2345 return NULL;
2346 }
2347 free(wnamebuf);
2348 return d;
2349 }
2350 /* Drop the argument parsing error as narrow strings
2351 are also valid. */
2352 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002353
Victor Stinner8c62be82010-05-06 00:08:46 +00002354 if (!PyArg_ParseTuple(args, "O&:listdir",
2355 PyUnicode_FSConverter, &opath))
2356 return NULL;
2357 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2358 PyErr_SetString(PyExc_ValueError, "path too long");
2359 Py_DECREF(opath);
2360 return NULL;
2361 }
2362 strcpy(namebuf, PyBytes_AsString(opath));
2363 len = PyObject_Size(opath);
2364 if (len > 0) {
2365 char ch = namebuf[len-1];
2366 if (ch != SEP && ch != ALTSEP && ch != ':')
2367 namebuf[len++] = '/';
2368 strcpy(namebuf + len, "*.*");
2369 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002370
Victor Stinner8c62be82010-05-06 00:08:46 +00002371 if ((d = PyList_New(0)) == NULL)
2372 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002373
Antoine Pitroub73caab2010-08-09 23:39:31 +00002374 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002375 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002376 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002377 if (hFindFile == INVALID_HANDLE_VALUE) {
2378 int error = GetLastError();
2379 if (error == ERROR_FILE_NOT_FOUND)
2380 return d;
2381 Py_DECREF(d);
2382 return win32_error("FindFirstFile", namebuf);
2383 }
2384 do {
2385 /* Skip over . and .. */
2386 if (strcmp(FileData.cFileName, ".") != 0 &&
2387 strcmp(FileData.cFileName, "..") != 0) {
2388 v = PyBytes_FromString(FileData.cFileName);
2389 if (v == NULL) {
2390 Py_DECREF(d);
2391 d = NULL;
2392 break;
2393 }
2394 if (PyList_Append(d, v) != 0) {
2395 Py_DECREF(v);
2396 Py_DECREF(d);
2397 d = NULL;
2398 break;
2399 }
2400 Py_DECREF(v);
2401 }
2402 Py_BEGIN_ALLOW_THREADS
2403 result = FindNextFile(hFindFile, &FileData);
2404 Py_END_ALLOW_THREADS
2405 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2406 it got to the end of the directory. */
2407 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2408 Py_DECREF(d);
2409 win32_error("FindNextFile", namebuf);
2410 FindClose(hFindFile);
2411 return NULL;
2412 }
2413 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002414
Victor Stinner8c62be82010-05-06 00:08:46 +00002415 if (FindClose(hFindFile) == FALSE) {
2416 Py_DECREF(d);
2417 return win32_error("FindClose", namebuf);
2418 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002419
Victor Stinner8c62be82010-05-06 00:08:46 +00002420 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002421
Tim Peters0bb44a42000-09-15 07:44:49 +00002422#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002423
2424#ifndef MAX_PATH
2425#define MAX_PATH CCHMAXPATH
2426#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002427 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002428 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002429 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002430 PyObject *d, *v;
2431 char namebuf[MAX_PATH+5];
2432 HDIR hdir = 1;
2433 ULONG srchcnt = 1;
2434 FILEFINDBUF3 ep;
2435 APIRET rc;
2436
Victor Stinner8c62be82010-05-06 00:08:46 +00002437 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002438 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002439 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002440 name = PyBytes_AsString(oname);
2441 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002442 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002443 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002444 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002445 return NULL;
2446 }
2447 strcpy(namebuf, name);
2448 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002449 if (*pt == ALTSEP)
2450 *pt = SEP;
2451 if (namebuf[len-1] != SEP)
2452 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002453 strcpy(namebuf + len, "*.*");
2454
Neal Norwitz6c913782007-10-14 03:23:09 +00002455 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002456 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002457 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002458 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002459
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002460 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2461 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002462 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002463 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2464 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2465 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002466
2467 if (rc != NO_ERROR) {
2468 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002469 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002470 }
2471
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002472 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002473 do {
2474 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002475 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002476 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002477
2478 strcpy(namebuf, ep.achName);
2479
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002480 /* Leave Case of Name Alone -- In Native Form */
2481 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002482
Christian Heimes72b710a2008-05-26 13:28:38 +00002483 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002484 if (v == NULL) {
2485 Py_DECREF(d);
2486 d = NULL;
2487 break;
2488 }
2489 if (PyList_Append(d, v) != 0) {
2490 Py_DECREF(v);
2491 Py_DECREF(d);
2492 d = NULL;
2493 break;
2494 }
2495 Py_DECREF(v);
2496 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2497 }
2498
Victor Stinnerdcb24032010-04-22 12:08:36 +00002499 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002500 return d;
2501#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002502 PyObject *oname;
2503 char *name;
2504 PyObject *d, *v;
2505 DIR *dirp;
2506 struct dirent *ep;
2507 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002508
Victor Stinner8c62be82010-05-06 00:08:46 +00002509 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002510 /* v is never read, so it does not need to be initialized yet. */
2511 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002512 arg_is_unicode = 0;
2513 PyErr_Clear();
2514 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002515 oname = NULL;
2516 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002517 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002518 if (oname == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002519 oname = PyBytes_FromString(".");
2520 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002521 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002522 Py_BEGIN_ALLOW_THREADS
2523 dirp = opendir(name);
2524 Py_END_ALLOW_THREADS
2525 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002526 return posix_error_with_allocated_filename(oname);
2527 }
2528 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002529 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002530 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002531 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002532 Py_DECREF(oname);
2533 return NULL;
2534 }
2535 for (;;) {
2536 errno = 0;
2537 Py_BEGIN_ALLOW_THREADS
2538 ep = readdir(dirp);
2539 Py_END_ALLOW_THREADS
2540 if (ep == NULL) {
2541 if (errno == 0) {
2542 break;
2543 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002544 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002545 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002546 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002547 Py_DECREF(d);
2548 return posix_error_with_allocated_filename(oname);
2549 }
2550 }
2551 if (ep->d_name[0] == '.' &&
2552 (NAMLEN(ep) == 1 ||
2553 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2554 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002555 if (arg_is_unicode)
2556 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2557 else
2558 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002559 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002560 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002561 break;
2562 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002563 if (PyList_Append(d, v) != 0) {
2564 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002565 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002566 break;
2567 }
2568 Py_DECREF(v);
2569 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002570 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002571 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002572 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002573 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002574
Victor Stinner8c62be82010-05-06 00:08:46 +00002575 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002576
Tim Peters0bb44a42000-09-15 07:44:49 +00002577#endif /* which OS */
2578} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002579
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002580#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002581/* A helper function for abspath on win32 */
2582static PyObject *
2583posix__getfullpathname(PyObject *self, PyObject *args)
2584{
Victor Stinner8c62be82010-05-06 00:08:46 +00002585 PyObject *opath;
2586 char *path;
2587 char outbuf[MAX_PATH*2];
2588 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002589#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002590 PyUnicodeObject *po;
2591 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2592 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2593 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2594 Py_UNICODE *wtemp;
2595 DWORD result;
2596 PyObject *v;
2597 result = GetFullPathNameW(wpath,
2598 sizeof(woutbuf)/sizeof(woutbuf[0]),
2599 woutbuf, &wtemp);
2600 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2601 woutbufp = malloc(result * sizeof(Py_UNICODE));
2602 if (!woutbufp)
2603 return PyErr_NoMemory();
2604 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2605 }
2606 if (result)
2607 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2608 else
2609 v = win32_error_unicode("GetFullPathNameW", wpath);
2610 if (woutbufp != woutbuf)
2611 free(woutbufp);
2612 return v;
2613 }
2614 /* Drop the argument parsing error as narrow strings
2615 are also valid. */
2616 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002617
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002618#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002619 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2620 PyUnicode_FSConverter, &opath))
2621 return NULL;
2622 path = PyBytes_AsString(opath);
2623 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2624 outbuf, &temp)) {
2625 win32_error("GetFullPathName", path);
2626 Py_DECREF(opath);
2627 return NULL;
2628 }
2629 Py_DECREF(opath);
2630 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2631 return PyUnicode_Decode(outbuf, strlen(outbuf),
2632 Py_FileSystemDefaultEncoding, NULL);
2633 }
2634 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002635} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002636
Brian Curtinf5e76d02010-11-24 13:14:05 +00002637/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
2638static int has_GetFinalPathNameByHandle = 0;
2639static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
2640 DWORD);
2641static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
2642 DWORD);
2643static int
2644check_GetFinalPathNameByHandle()
2645{
2646 HINSTANCE hKernel32;
2647 /* only recheck */
2648 if (!has_GetFinalPathNameByHandle)
2649 {
2650 hKernel32 = GetModuleHandle("KERNEL32");
2651 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
2652 "GetFinalPathNameByHandleA");
2653 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
2654 "GetFinalPathNameByHandleW");
2655 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
2656 Py_GetFinalPathNameByHandleW;
2657 }
2658 return has_GetFinalPathNameByHandle;
2659}
2660
Brian Curtind40e6f72010-07-08 21:39:08 +00002661/* A helper function for samepath on windows */
2662static PyObject *
2663posix__getfinalpathname(PyObject *self, PyObject *args)
2664{
2665 HANDLE hFile;
2666 int buf_size;
2667 wchar_t *target_path;
2668 int result_length;
2669 PyObject *result;
2670 wchar_t *path;
2671
Brian Curtin94622b02010-09-24 00:03:39 +00002672 if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) {
Brian Curtind40e6f72010-07-08 21:39:08 +00002673 return NULL;
2674 }
2675
2676 if(!check_GetFinalPathNameByHandle()) {
2677 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2678 NotImplementedError. */
2679 return PyErr_Format(PyExc_NotImplementedError,
2680 "GetFinalPathNameByHandle not available on this platform");
2681 }
2682
2683 hFile = CreateFileW(
2684 path,
2685 0, /* desired access */
2686 0, /* share mode */
2687 NULL, /* security attributes */
2688 OPEN_EXISTING,
2689 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2690 FILE_FLAG_BACKUP_SEMANTICS,
2691 NULL);
2692
2693 if(hFile == INVALID_HANDLE_VALUE) {
2694 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002695 return PyErr_Format(PyExc_RuntimeError,
2696 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002697 }
2698
2699 /* We have a good handle to the target, use it to determine the
2700 target path name. */
2701 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2702
2703 if(!buf_size)
2704 return win32_error_unicode("GetFinalPathNameByHandle", path);
2705
2706 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2707 if(!target_path)
2708 return PyErr_NoMemory();
2709
2710 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2711 buf_size, VOLUME_NAME_DOS);
2712 if(!result_length)
2713 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2714
2715 if(!CloseHandle(hFile))
2716 return win32_error_unicode("GetFinalPathNameByHandle", path);
2717
2718 target_path[result_length] = 0;
2719 result = PyUnicode_FromUnicode(target_path, result_length);
2720 free(target_path);
2721 return result;
2722
2723} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00002724
2725static PyObject *
2726posix__getfileinformation(PyObject *self, PyObject *args)
2727{
2728 HANDLE hFile;
2729 BY_HANDLE_FILE_INFORMATION info;
2730 int fd;
2731
2732 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
2733 return NULL;
2734
2735 if (!_PyVerify_fd(fd)) {
2736 PyErr_SetString(PyExc_ValueError, "received invalid file descriptor");
2737 return NULL;
2738 }
2739
2740 hFile = (HANDLE)_get_osfhandle(fd);
2741 if (hFile == INVALID_HANDLE_VALUE)
2742 return win32_error("_getfileinformation", NULL);
2743
2744 if (!GetFileInformationByHandle(hFile, &info))
2745 return win32_error("_getfileinformation", NULL);
2746
2747 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
2748 info.nFileIndexHigh,
2749 info.nFileIndexLow);
2750}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002751#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002752
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002753PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002754"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002755Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002756
Barry Warsaw53699e91996-12-10 23:23:01 +00002757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002758posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002759{
Victor Stinner8c62be82010-05-06 00:08:46 +00002760 int res;
2761 PyObject *opath;
2762 char *path;
2763 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002764
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002765#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002766 PyUnicodeObject *po;
2767 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2768 Py_BEGIN_ALLOW_THREADS
2769 /* PyUnicode_AS_UNICODE OK without thread lock as
2770 it is a simple dereference. */
2771 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2772 Py_END_ALLOW_THREADS
2773 if (!res)
2774 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2775 Py_INCREF(Py_None);
2776 return Py_None;
2777 }
2778 /* Drop the argument parsing error as narrow strings
2779 are also valid. */
2780 PyErr_Clear();
2781 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2782 PyUnicode_FSConverter, &opath, &mode))
2783 return NULL;
2784 path = PyBytes_AsString(opath);
2785 Py_BEGIN_ALLOW_THREADS
2786 /* PyUnicode_AS_UNICODE OK without thread lock as
2787 it is a simple dereference. */
2788 res = CreateDirectoryA(path, NULL);
2789 Py_END_ALLOW_THREADS
2790 if (!res) {
2791 win32_error("mkdir", path);
2792 Py_DECREF(opath);
2793 return NULL;
2794 }
2795 Py_DECREF(opath);
2796 Py_INCREF(Py_None);
2797 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002798#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002799
Victor Stinner8c62be82010-05-06 00:08:46 +00002800 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2801 PyUnicode_FSConverter, &opath, &mode))
2802 return NULL;
2803 path = PyBytes_AsString(opath);
2804 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002805#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002806 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002807#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002808 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002809#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002810 Py_END_ALLOW_THREADS
2811 if (res < 0)
2812 return posix_error_with_allocated_filename(opath);
2813 Py_DECREF(opath);
2814 Py_INCREF(Py_None);
2815 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002816#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002817}
2818
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002819
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002820/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2821#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002822#include <sys/resource.h>
2823#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002824
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002825
2826#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002827PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002828"nice(inc) -> new_priority\n\n\
2829Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002830
Barry Warsaw53699e91996-12-10 23:23:01 +00002831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002832posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002833{
Victor Stinner8c62be82010-05-06 00:08:46 +00002834 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002835
Victor Stinner8c62be82010-05-06 00:08:46 +00002836 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2837 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002838
Victor Stinner8c62be82010-05-06 00:08:46 +00002839 /* There are two flavours of 'nice': one that returns the new
2840 priority (as required by almost all standards out there) and the
2841 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2842 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002843
Victor Stinner8c62be82010-05-06 00:08:46 +00002844 If we are of the nice family that returns the new priority, we
2845 need to clear errno before the call, and check if errno is filled
2846 before calling posix_error() on a returnvalue of -1, because the
2847 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002848
Victor Stinner8c62be82010-05-06 00:08:46 +00002849 errno = 0;
2850 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002851#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00002852 if (value == 0)
2853 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002854#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002855 if (value == -1 && errno != 0)
2856 /* either nice() or getpriority() returned an error */
2857 return posix_error();
2858 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002859}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002860#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002861
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002862PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002863"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002864Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002865
Barry Warsaw53699e91996-12-10 23:23:01 +00002866static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002867posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002868{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002869#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002870 PyObject *o1, *o2;
2871 char *p1, *p2;
2872 BOOL result;
2873 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2874 goto error;
2875 if (!convert_to_unicode(&o1))
2876 goto error;
2877 if (!convert_to_unicode(&o2)) {
2878 Py_DECREF(o1);
2879 goto error;
2880 }
2881 Py_BEGIN_ALLOW_THREADS
2882 result = MoveFileW(PyUnicode_AsUnicode(o1),
2883 PyUnicode_AsUnicode(o2));
2884 Py_END_ALLOW_THREADS
2885 Py_DECREF(o1);
2886 Py_DECREF(o2);
2887 if (!result)
2888 return win32_error("rename", NULL);
2889 Py_INCREF(Py_None);
2890 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002891error:
Victor Stinner8c62be82010-05-06 00:08:46 +00002892 PyErr_Clear();
2893 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2894 return NULL;
2895 Py_BEGIN_ALLOW_THREADS
2896 result = MoveFileA(p1, p2);
2897 Py_END_ALLOW_THREADS
2898 if (!result)
2899 return win32_error("rename", NULL);
2900 Py_INCREF(Py_None);
2901 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002902#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002903 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002904#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002905}
2906
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002907
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002908PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002909"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002910Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002911
Barry Warsaw53699e91996-12-10 23:23:01 +00002912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002913posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002914{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002915#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002916 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002917#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002918 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002919#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002920}
2921
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002922
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002923PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002924"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002925Perform a stat system call on the given path.");
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_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002929{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002930#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00002931 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002932#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002933 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002934#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002935}
2936
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002937
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002938#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002939PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002940"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002941Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002942
Barry Warsaw53699e91996-12-10 23:23:01 +00002943static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002944posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002945{
Victor Stinner8c62be82010-05-06 00:08:46 +00002946 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002947#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002948 wchar_t *command;
2949 if (!PyArg_ParseTuple(args, "u:system", &command))
2950 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002951
Victor Stinner8c62be82010-05-06 00:08:46 +00002952 Py_BEGIN_ALLOW_THREADS
2953 sts = _wsystem(command);
2954 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00002955#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002956 PyObject *command_obj;
2957 char *command;
2958 if (!PyArg_ParseTuple(args, "O&:system",
2959 PyUnicode_FSConverter, &command_obj))
2960 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002961
Victor Stinner8c62be82010-05-06 00:08:46 +00002962 command = PyBytes_AsString(command_obj);
2963 Py_BEGIN_ALLOW_THREADS
2964 sts = system(command);
2965 Py_END_ALLOW_THREADS
2966 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00002967#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002968 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002969}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002970#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002971
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002972
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002973PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002974"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002975Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002976
Barry Warsaw53699e91996-12-10 23:23:01 +00002977static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002978posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002979{
Victor Stinner8c62be82010-05-06 00:08:46 +00002980 int i;
2981 if (!PyArg_ParseTuple(args, "i:umask", &i))
2982 return NULL;
2983 i = (int)umask(i);
2984 if (i < 0)
2985 return posix_error();
2986 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002987}
2988
Brian Curtind40e6f72010-07-08 21:39:08 +00002989#ifdef MS_WINDOWS
2990
2991/* override the default DeleteFileW behavior so that directory
2992symlinks can be removed with this function, the same as with
2993Unix symlinks */
2994BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
2995{
2996 WIN32_FILE_ATTRIBUTE_DATA info;
2997 WIN32_FIND_DATAW find_data;
2998 HANDLE find_data_handle;
2999 int is_directory = 0;
3000 int is_link = 0;
3001
3002 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3003 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
3004
3005 /* Get WIN32_FIND_DATA structure for the path to determine if
3006 it is a symlink */
3007 if(is_directory &&
3008 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3009 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3010
3011 if(find_data_handle != INVALID_HANDLE_VALUE) {
3012 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3013 FindClose(find_data_handle);
3014 }
3015 }
3016 }
3017
3018 if (is_directory && is_link)
3019 return RemoveDirectoryW(lpFileName);
3020
3021 return DeleteFileW(lpFileName);
3022}
3023#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003024
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003025PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003026"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003027Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003028
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003029PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003030"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003031Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003032
Barry Warsaw53699e91996-12-10 23:23:01 +00003033static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003034posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003035{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003036#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003037 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3038 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003039#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003040 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003041#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003042}
3043
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003044
Guido van Rossumb6775db1994-08-01 11:34:53 +00003045#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003046PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003047"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003048Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003049
Barry Warsaw53699e91996-12-10 23:23:01 +00003050static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003051posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003052{
Victor Stinner8c62be82010-05-06 00:08:46 +00003053 struct utsname u;
3054 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003055
Victor Stinner8c62be82010-05-06 00:08:46 +00003056 Py_BEGIN_ALLOW_THREADS
3057 res = uname(&u);
3058 Py_END_ALLOW_THREADS
3059 if (res < 0)
3060 return posix_error();
3061 return Py_BuildValue("(sssss)",
3062 u.sysname,
3063 u.nodename,
3064 u.release,
3065 u.version,
3066 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003067}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003068#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003069
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003070static int
3071extract_time(PyObject *t, long* sec, long* usec)
3072{
Victor Stinner8c62be82010-05-06 00:08:46 +00003073 long intval;
3074 if (PyFloat_Check(t)) {
3075 double tval = PyFloat_AsDouble(t);
3076 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
3077 if (!intobj)
3078 return -1;
3079 intval = PyLong_AsLong(intobj);
3080 Py_DECREF(intobj);
3081 if (intval == -1 && PyErr_Occurred())
3082 return -1;
3083 *sec = intval;
3084 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3085 if (*usec < 0)
3086 /* If rounding gave us a negative number,
3087 truncate. */
3088 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003089 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003090 }
3091 intval = PyLong_AsLong(t);
3092 if (intval == -1 && PyErr_Occurred())
3093 return -1;
3094 *sec = intval;
3095 *usec = 0;
3096 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003097}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003098
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003099PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003100"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003101utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003102Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003103second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003104
Barry Warsaw53699e91996-12-10 23:23:01 +00003105static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003106posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003107{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003108#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003109 PyObject *arg;
3110 PyUnicodeObject *obwpath;
3111 wchar_t *wpath = NULL;
3112 PyObject *oapath;
3113 char *apath;
3114 HANDLE hFile;
3115 long atimesec, mtimesec, ausec, musec;
3116 FILETIME atime, mtime;
3117 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003118
Victor Stinner8c62be82010-05-06 00:08:46 +00003119 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3120 wpath = PyUnicode_AS_UNICODE(obwpath);
3121 Py_BEGIN_ALLOW_THREADS
3122 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3123 NULL, OPEN_EXISTING,
3124 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3125 Py_END_ALLOW_THREADS
3126 if (hFile == INVALID_HANDLE_VALUE)
3127 return win32_error_unicode("utime", wpath);
3128 } else
3129 /* Drop the argument parsing error as narrow strings
3130 are also valid. */
3131 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003132
Victor Stinner8c62be82010-05-06 00:08:46 +00003133 if (!wpath) {
3134 if (!PyArg_ParseTuple(args, "O&O:utime",
3135 PyUnicode_FSConverter, &oapath, &arg))
3136 return NULL;
3137 apath = PyBytes_AsString(oapath);
3138 Py_BEGIN_ALLOW_THREADS
3139 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3140 NULL, OPEN_EXISTING,
3141 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3142 Py_END_ALLOW_THREADS
3143 if (hFile == INVALID_HANDLE_VALUE) {
3144 win32_error("utime", apath);
3145 Py_DECREF(oapath);
3146 return NULL;
3147 }
3148 Py_DECREF(oapath);
3149 }
3150
3151 if (arg == Py_None) {
3152 SYSTEMTIME now;
3153 GetSystemTime(&now);
3154 if (!SystemTimeToFileTime(&now, &mtime) ||
3155 !SystemTimeToFileTime(&now, &atime)) {
3156 win32_error("utime", NULL);
3157 goto done;
3158 }
3159 }
3160 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3161 PyErr_SetString(PyExc_TypeError,
3162 "utime() arg 2 must be a tuple (atime, mtime)");
3163 goto done;
3164 }
3165 else {
3166 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3167 &atimesec, &ausec) == -1)
3168 goto done;
3169 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3170 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3171 &mtimesec, &musec) == -1)
3172 goto done;
3173 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3174 }
3175 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3176 /* Avoid putting the file name into the error here,
3177 as that may confuse the user into believing that
3178 something is wrong with the file, when it also
3179 could be the time stamp that gives a problem. */
3180 win32_error("utime", NULL);
3181 }
3182 Py_INCREF(Py_None);
3183 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003184done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003185 CloseHandle(hFile);
3186 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003187#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003188
Victor Stinner8c62be82010-05-06 00:08:46 +00003189 PyObject *opath;
3190 char *path;
3191 long atime, mtime, ausec, musec;
3192 int res;
3193 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003194
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003195#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003196 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003197#define ATIME buf[0].tv_sec
3198#define MTIME buf[1].tv_sec
3199#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003200/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003201 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003202#define ATIME buf.actime
3203#define MTIME buf.modtime
3204#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003205#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003206 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003207#define ATIME buf[0]
3208#define MTIME buf[1]
3209#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003210#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003211
Mark Hammond817c9292003-12-03 01:22:38 +00003212
Victor Stinner8c62be82010-05-06 00:08:46 +00003213 if (!PyArg_ParseTuple(args, "O&O:utime",
3214 PyUnicode_FSConverter, &opath, &arg))
3215 return NULL;
3216 path = PyBytes_AsString(opath);
3217 if (arg == Py_None) {
3218 /* optional time values not given */
3219 Py_BEGIN_ALLOW_THREADS
3220 res = utime(path, NULL);
3221 Py_END_ALLOW_THREADS
3222 }
3223 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3224 PyErr_SetString(PyExc_TypeError,
3225 "utime() arg 2 must be a tuple (atime, mtime)");
3226 Py_DECREF(opath);
3227 return NULL;
3228 }
3229 else {
3230 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3231 &atime, &ausec) == -1) {
3232 Py_DECREF(opath);
3233 return NULL;
3234 }
3235 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3236 &mtime, &musec) == -1) {
3237 Py_DECREF(opath);
3238 return NULL;
3239 }
3240 ATIME = atime;
3241 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003242#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003243 buf[0].tv_usec = ausec;
3244 buf[1].tv_usec = musec;
3245 Py_BEGIN_ALLOW_THREADS
3246 res = utimes(path, buf);
3247 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003248#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003249 Py_BEGIN_ALLOW_THREADS
3250 res = utime(path, UTIME_ARG);
3251 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003252#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003253 }
3254 if (res < 0) {
3255 return posix_error_with_allocated_filename(opath);
3256 }
3257 Py_DECREF(opath);
3258 Py_INCREF(Py_None);
3259 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003260#undef UTIME_ARG
3261#undef ATIME
3262#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003263#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003264}
3265
Guido van Rossum85e3b011991-06-03 12:42:10 +00003266
Guido van Rossum3b066191991-06-04 19:40:25 +00003267/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003268
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003269PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003270"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003271Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003272
Barry Warsaw53699e91996-12-10 23:23:01 +00003273static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003274posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003275{
Victor Stinner8c62be82010-05-06 00:08:46 +00003276 int sts;
3277 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3278 return NULL;
3279 _exit(sts);
3280 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003281}
3282
Martin v. Löwis114619e2002-10-07 06:44:21 +00003283#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3284static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003285free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003286{
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 Py_ssize_t i;
3288 for (i = 0; i < count; i++)
3289 PyMem_Free(array[i]);
3290 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003291}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003292
Antoine Pitrou69f71142009-05-24 21:25:49 +00003293static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003294int fsconvert_strdup(PyObject *o, char**out)
3295{
Victor Stinner8c62be82010-05-06 00:08:46 +00003296 PyObject *bytes;
3297 Py_ssize_t size;
3298 if (!PyUnicode_FSConverter(o, &bytes))
3299 return 0;
3300 size = PyBytes_GET_SIZE(bytes);
3301 *out = PyMem_Malloc(size+1);
3302 if (!*out)
3303 return 0;
3304 memcpy(*out, PyBytes_AsString(bytes), size+1);
3305 Py_DECREF(bytes);
3306 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003307}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003308#endif
3309
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003310
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003311#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003312PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003313"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003314Execute an executable path with arguments, replacing current process.\n\
3315\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003316 path: path of executable file\n\
3317 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003318
Barry Warsaw53699e91996-12-10 23:23:01 +00003319static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003320posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003321{
Victor Stinner8c62be82010-05-06 00:08:46 +00003322 PyObject *opath;
3323 char *path;
3324 PyObject *argv;
3325 char **argvlist;
3326 Py_ssize_t i, argc;
3327 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003328
Victor Stinner8c62be82010-05-06 00:08:46 +00003329 /* execv has two arguments: (path, argv), where
3330 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003331
Victor Stinner8c62be82010-05-06 00:08:46 +00003332 if (!PyArg_ParseTuple(args, "O&O:execv",
3333 PyUnicode_FSConverter,
3334 &opath, &argv))
3335 return NULL;
3336 path = PyBytes_AsString(opath);
3337 if (PyList_Check(argv)) {
3338 argc = PyList_Size(argv);
3339 getitem = PyList_GetItem;
3340 }
3341 else if (PyTuple_Check(argv)) {
3342 argc = PyTuple_Size(argv);
3343 getitem = PyTuple_GetItem;
3344 }
3345 else {
3346 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3347 Py_DECREF(opath);
3348 return NULL;
3349 }
3350 if (argc < 1) {
3351 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3352 Py_DECREF(opath);
3353 return NULL;
3354 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003355
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 argvlist = PyMem_NEW(char *, argc+1);
3357 if (argvlist == NULL) {
3358 Py_DECREF(opath);
3359 return PyErr_NoMemory();
3360 }
3361 for (i = 0; i < argc; i++) {
3362 if (!fsconvert_strdup((*getitem)(argv, i),
3363 &argvlist[i])) {
3364 free_string_array(argvlist, i);
3365 PyErr_SetString(PyExc_TypeError,
3366 "execv() arg 2 must contain only strings");
3367 Py_DECREF(opath);
3368 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003369
Victor Stinner8c62be82010-05-06 00:08:46 +00003370 }
3371 }
3372 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003373
Victor Stinner8c62be82010-05-06 00:08:46 +00003374 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003375
Victor Stinner8c62be82010-05-06 00:08:46 +00003376 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003377
Victor Stinner8c62be82010-05-06 00:08:46 +00003378 free_string_array(argvlist, argc);
3379 Py_DECREF(opath);
3380 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003381}
3382
Victor Stinner13bb71c2010-04-23 21:41:56 +00003383static char**
3384parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3385{
Victor Stinner8c62be82010-05-06 00:08:46 +00003386 char **envlist;
3387 Py_ssize_t i, pos, envc;
3388 PyObject *keys=NULL, *vals=NULL;
3389 PyObject *key, *val, *key2, *val2;
3390 char *p, *k, *v;
3391 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003392
Victor Stinner8c62be82010-05-06 00:08:46 +00003393 i = PyMapping_Size(env);
3394 if (i < 0)
3395 return NULL;
3396 envlist = PyMem_NEW(char *, i + 1);
3397 if (envlist == NULL) {
3398 PyErr_NoMemory();
3399 return NULL;
3400 }
3401 envc = 0;
3402 keys = PyMapping_Keys(env);
3403 vals = PyMapping_Values(env);
3404 if (!keys || !vals)
3405 goto error;
3406 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3407 PyErr_Format(PyExc_TypeError,
3408 "env.keys() or env.values() is not a list");
3409 goto error;
3410 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003411
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 for (pos = 0; pos < i; pos++) {
3413 key = PyList_GetItem(keys, pos);
3414 val = PyList_GetItem(vals, pos);
3415 if (!key || !val)
3416 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003417
Victor Stinner8c62be82010-05-06 00:08:46 +00003418 if (PyUnicode_FSConverter(key, &key2) == 0)
3419 goto error;
3420 if (PyUnicode_FSConverter(val, &val2) == 0) {
3421 Py_DECREF(key2);
3422 goto error;
3423 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003424
3425#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003426 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3427 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003428#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003429 k = PyBytes_AsString(key2);
3430 v = PyBytes_AsString(val2);
3431 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003432
Victor Stinner8c62be82010-05-06 00:08:46 +00003433 p = PyMem_NEW(char, len);
3434 if (p == NULL) {
3435 PyErr_NoMemory();
3436 Py_DECREF(key2);
3437 Py_DECREF(val2);
3438 goto error;
3439 }
3440 PyOS_snprintf(p, len, "%s=%s", k, v);
3441 envlist[envc++] = p;
3442 Py_DECREF(key2);
3443 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003444#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003445 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003446#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003447 }
3448 Py_DECREF(vals);
3449 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003450
Victor Stinner8c62be82010-05-06 00:08:46 +00003451 envlist[envc] = 0;
3452 *envc_ptr = envc;
3453 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003454
3455error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003456 Py_XDECREF(keys);
3457 Py_XDECREF(vals);
3458 while (--envc >= 0)
3459 PyMem_DEL(envlist[envc]);
3460 PyMem_DEL(envlist);
3461 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003462}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003463
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003464PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003465"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003466Execute a path with arguments and environment, replacing current process.\n\
3467\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003468 path: path of executable file\n\
3469 args: tuple or list of arguments\n\
3470 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003471
Barry Warsaw53699e91996-12-10 23:23:01 +00003472static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003473posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003474{
Victor Stinner8c62be82010-05-06 00:08:46 +00003475 PyObject *opath;
3476 char *path;
3477 PyObject *argv, *env;
3478 char **argvlist;
3479 char **envlist;
3480 Py_ssize_t i, argc, envc;
3481 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3482 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003483
Victor Stinner8c62be82010-05-06 00:08:46 +00003484 /* execve has three arguments: (path, argv, env), where
3485 argv is a list or tuple of strings and env is a dictionary
3486 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003487
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 if (!PyArg_ParseTuple(args, "O&OO:execve",
3489 PyUnicode_FSConverter,
3490 &opath, &argv, &env))
3491 return NULL;
3492 path = PyBytes_AsString(opath);
3493 if (PyList_Check(argv)) {
3494 argc = PyList_Size(argv);
3495 getitem = PyList_GetItem;
3496 }
3497 else if (PyTuple_Check(argv)) {
3498 argc = PyTuple_Size(argv);
3499 getitem = PyTuple_GetItem;
3500 }
3501 else {
3502 PyErr_SetString(PyExc_TypeError,
3503 "execve() arg 2 must be a tuple or list");
3504 goto fail_0;
3505 }
3506 if (!PyMapping_Check(env)) {
3507 PyErr_SetString(PyExc_TypeError,
3508 "execve() arg 3 must be a mapping object");
3509 goto fail_0;
3510 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003511
Victor Stinner8c62be82010-05-06 00:08:46 +00003512 argvlist = PyMem_NEW(char *, argc+1);
3513 if (argvlist == NULL) {
3514 PyErr_NoMemory();
3515 goto fail_0;
3516 }
3517 for (i = 0; i < argc; i++) {
3518 if (!fsconvert_strdup((*getitem)(argv, i),
3519 &argvlist[i]))
3520 {
3521 lastarg = i;
3522 goto fail_1;
3523 }
3524 }
3525 lastarg = argc;
3526 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003527
Victor Stinner8c62be82010-05-06 00:08:46 +00003528 envlist = parse_envlist(env, &envc);
3529 if (envlist == NULL)
3530 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003531
Victor Stinner8c62be82010-05-06 00:08:46 +00003532 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003533
Victor Stinner8c62be82010-05-06 00:08:46 +00003534 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003535
Victor Stinner8c62be82010-05-06 00:08:46 +00003536 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003537
Victor Stinner8c62be82010-05-06 00:08:46 +00003538 while (--envc >= 0)
3539 PyMem_DEL(envlist[envc]);
3540 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003541 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003542 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003543 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003544 Py_DECREF(opath);
3545 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003546}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003547#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003548
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003549
Guido van Rossuma1065681999-01-25 23:20:23 +00003550#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003551PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003552"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003553Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003554\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003555 mode: mode of process creation\n\
3556 path: path of executable file\n\
3557 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003558
3559static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003560posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003561{
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 PyObject *opath;
3563 char *path;
3564 PyObject *argv;
3565 char **argvlist;
3566 int mode, i;
3567 Py_ssize_t argc;
3568 Py_intptr_t spawnval;
3569 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003570
Victor Stinner8c62be82010-05-06 00:08:46 +00003571 /* spawnv has three arguments: (mode, path, argv), where
3572 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003573
Victor Stinner8c62be82010-05-06 00:08:46 +00003574 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3575 PyUnicode_FSConverter,
3576 &opath, &argv))
3577 return NULL;
3578 path = PyBytes_AsString(opath);
3579 if (PyList_Check(argv)) {
3580 argc = PyList_Size(argv);
3581 getitem = PyList_GetItem;
3582 }
3583 else if (PyTuple_Check(argv)) {
3584 argc = PyTuple_Size(argv);
3585 getitem = PyTuple_GetItem;
3586 }
3587 else {
3588 PyErr_SetString(PyExc_TypeError,
3589 "spawnv() arg 2 must be a tuple or list");
3590 Py_DECREF(opath);
3591 return NULL;
3592 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003593
Victor Stinner8c62be82010-05-06 00:08:46 +00003594 argvlist = PyMem_NEW(char *, argc+1);
3595 if (argvlist == NULL) {
3596 Py_DECREF(opath);
3597 return PyErr_NoMemory();
3598 }
3599 for (i = 0; i < argc; i++) {
3600 if (!fsconvert_strdup((*getitem)(argv, i),
3601 &argvlist[i])) {
3602 free_string_array(argvlist, i);
3603 PyErr_SetString(
3604 PyExc_TypeError,
3605 "spawnv() arg 2 must contain only strings");
3606 Py_DECREF(opath);
3607 return NULL;
3608 }
3609 }
3610 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003611
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003612#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003613 Py_BEGIN_ALLOW_THREADS
3614 spawnval = spawnv(mode, path, argvlist);
3615 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003616#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003617 if (mode == _OLD_P_OVERLAY)
3618 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003619
Victor Stinner8c62be82010-05-06 00:08:46 +00003620 Py_BEGIN_ALLOW_THREADS
3621 spawnval = _spawnv(mode, path, argvlist);
3622 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003623#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003624
Victor Stinner8c62be82010-05-06 00:08:46 +00003625 free_string_array(argvlist, argc);
3626 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003627
Victor Stinner8c62be82010-05-06 00:08:46 +00003628 if (spawnval == -1)
3629 return posix_error();
3630 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003631#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003632 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003633#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003634 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003635#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003636}
3637
3638
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003639PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003640"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003641Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003642\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003643 mode: mode of process creation\n\
3644 path: path of executable file\n\
3645 args: tuple or list of arguments\n\
3646 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003647
3648static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003649posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003650{
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 PyObject *opath;
3652 char *path;
3653 PyObject *argv, *env;
3654 char **argvlist;
3655 char **envlist;
3656 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003657 int mode;
3658 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003659 Py_intptr_t spawnval;
3660 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3661 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003662
Victor Stinner8c62be82010-05-06 00:08:46 +00003663 /* spawnve has four arguments: (mode, path, argv, env), where
3664 argv is a list or tuple of strings and env is a dictionary
3665 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003666
Victor Stinner8c62be82010-05-06 00:08:46 +00003667 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3668 PyUnicode_FSConverter,
3669 &opath, &argv, &env))
3670 return NULL;
3671 path = PyBytes_AsString(opath);
3672 if (PyList_Check(argv)) {
3673 argc = PyList_Size(argv);
3674 getitem = PyList_GetItem;
3675 }
3676 else if (PyTuple_Check(argv)) {
3677 argc = PyTuple_Size(argv);
3678 getitem = PyTuple_GetItem;
3679 }
3680 else {
3681 PyErr_SetString(PyExc_TypeError,
3682 "spawnve() arg 2 must be a tuple or list");
3683 goto fail_0;
3684 }
3685 if (!PyMapping_Check(env)) {
3686 PyErr_SetString(PyExc_TypeError,
3687 "spawnve() arg 3 must be a mapping object");
3688 goto fail_0;
3689 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003690
Victor Stinner8c62be82010-05-06 00:08:46 +00003691 argvlist = PyMem_NEW(char *, argc+1);
3692 if (argvlist == NULL) {
3693 PyErr_NoMemory();
3694 goto fail_0;
3695 }
3696 for (i = 0; i < argc; i++) {
3697 if (!fsconvert_strdup((*getitem)(argv, i),
3698 &argvlist[i]))
3699 {
3700 lastarg = i;
3701 goto fail_1;
3702 }
3703 }
3704 lastarg = argc;
3705 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003706
Victor Stinner8c62be82010-05-06 00:08:46 +00003707 envlist = parse_envlist(env, &envc);
3708 if (envlist == NULL)
3709 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003710
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003711#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003712 Py_BEGIN_ALLOW_THREADS
3713 spawnval = spawnve(mode, path, argvlist, envlist);
3714 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003715#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003716 if (mode == _OLD_P_OVERLAY)
3717 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003718
Victor Stinner8c62be82010-05-06 00:08:46 +00003719 Py_BEGIN_ALLOW_THREADS
3720 spawnval = _spawnve(mode, path, argvlist, envlist);
3721 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003722#endif
Tim Peters25059d32001-12-07 20:35:43 +00003723
Victor Stinner8c62be82010-05-06 00:08:46 +00003724 if (spawnval == -1)
3725 (void) posix_error();
3726 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003727#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003728 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003729#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003730 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003731#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003732
Victor Stinner8c62be82010-05-06 00:08:46 +00003733 while (--envc >= 0)
3734 PyMem_DEL(envlist[envc]);
3735 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003736 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003737 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003738 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003739 Py_DECREF(opath);
3740 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003741}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003742
3743/* OS/2 supports spawnvp & spawnvpe natively */
3744#if defined(PYOS_OS2)
3745PyDoc_STRVAR(posix_spawnvp__doc__,
3746"spawnvp(mode, file, args)\n\n\
3747Execute the program 'file' in a new process, using the environment\n\
3748search path to find the file.\n\
3749\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003750 mode: mode of process creation\n\
3751 file: executable file name\n\
3752 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003753
3754static PyObject *
3755posix_spawnvp(PyObject *self, PyObject *args)
3756{
Victor Stinner8c62be82010-05-06 00:08:46 +00003757 PyObject *opath;
3758 char *path;
3759 PyObject *argv;
3760 char **argvlist;
3761 int mode, i, argc;
3762 Py_intptr_t spawnval;
3763 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003764
Victor Stinner8c62be82010-05-06 00:08:46 +00003765 /* spawnvp has three arguments: (mode, path, argv), where
3766 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003767
Victor Stinner8c62be82010-05-06 00:08:46 +00003768 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3769 PyUnicode_FSConverter,
3770 &opath, &argv))
3771 return NULL;
3772 path = PyBytes_AsString(opath);
3773 if (PyList_Check(argv)) {
3774 argc = PyList_Size(argv);
3775 getitem = PyList_GetItem;
3776 }
3777 else if (PyTuple_Check(argv)) {
3778 argc = PyTuple_Size(argv);
3779 getitem = PyTuple_GetItem;
3780 }
3781 else {
3782 PyErr_SetString(PyExc_TypeError,
3783 "spawnvp() arg 2 must be a tuple or list");
3784 Py_DECREF(opath);
3785 return NULL;
3786 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003787
Victor Stinner8c62be82010-05-06 00:08:46 +00003788 argvlist = PyMem_NEW(char *, argc+1);
3789 if (argvlist == NULL) {
3790 Py_DECREF(opath);
3791 return PyErr_NoMemory();
3792 }
3793 for (i = 0; i < argc; i++) {
3794 if (!fsconvert_strdup((*getitem)(argv, i),
3795 &argvlist[i])) {
3796 free_string_array(argvlist, i);
3797 PyErr_SetString(
3798 PyExc_TypeError,
3799 "spawnvp() arg 2 must contain only strings");
3800 Py_DECREF(opath);
3801 return NULL;
3802 }
3803 }
3804 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003805
Victor Stinner8c62be82010-05-06 00:08:46 +00003806 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003807#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003808 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003809#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003810 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003811#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003812 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003813
Victor Stinner8c62be82010-05-06 00:08:46 +00003814 free_string_array(argvlist, argc);
3815 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003816
Victor Stinner8c62be82010-05-06 00:08:46 +00003817 if (spawnval == -1)
3818 return posix_error();
3819 else
3820 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003821}
3822
3823
3824PyDoc_STRVAR(posix_spawnvpe__doc__,
3825"spawnvpe(mode, file, args, env)\n\n\
3826Execute the program 'file' in a new process, using the environment\n\
3827search path to find the file.\n\
3828\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003829 mode: mode of process creation\n\
3830 file: executable file name\n\
3831 args: tuple or list of arguments\n\
3832 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003833
3834static PyObject *
3835posix_spawnvpe(PyObject *self, PyObject *args)
3836{
Victor Stinner8c62be82010-05-06 00:08:46 +00003837 PyObject *opath
3838 char *path;
3839 PyObject *argv, *env;
3840 char **argvlist;
3841 char **envlist;
3842 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003843 int mode;
3844 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003845 Py_intptr_t spawnval;
3846 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3847 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003848
Victor Stinner8c62be82010-05-06 00:08:46 +00003849 /* spawnvpe has four arguments: (mode, path, argv, env), where
3850 argv is a list or tuple of strings and env is a dictionary
3851 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003852
Victor Stinner8c62be82010-05-06 00:08:46 +00003853 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3854 PyUnicode_FSConverter,
3855 &opath, &argv, &env))
3856 return NULL;
3857 path = PyBytes_AsString(opath);
3858 if (PyList_Check(argv)) {
3859 argc = PyList_Size(argv);
3860 getitem = PyList_GetItem;
3861 }
3862 else if (PyTuple_Check(argv)) {
3863 argc = PyTuple_Size(argv);
3864 getitem = PyTuple_GetItem;
3865 }
3866 else {
3867 PyErr_SetString(PyExc_TypeError,
3868 "spawnvpe() arg 2 must be a tuple or list");
3869 goto fail_0;
3870 }
3871 if (!PyMapping_Check(env)) {
3872 PyErr_SetString(PyExc_TypeError,
3873 "spawnvpe() arg 3 must be a mapping object");
3874 goto fail_0;
3875 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003876
Victor Stinner8c62be82010-05-06 00:08:46 +00003877 argvlist = PyMem_NEW(char *, argc+1);
3878 if (argvlist == NULL) {
3879 PyErr_NoMemory();
3880 goto fail_0;
3881 }
3882 for (i = 0; i < argc; i++) {
3883 if (!fsconvert_strdup((*getitem)(argv, i),
3884 &argvlist[i]))
3885 {
3886 lastarg = i;
3887 goto fail_1;
3888 }
3889 }
3890 lastarg = argc;
3891 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003892
Victor Stinner8c62be82010-05-06 00:08:46 +00003893 envlist = parse_envlist(env, &envc);
3894 if (envlist == NULL)
3895 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003896
Victor Stinner8c62be82010-05-06 00:08:46 +00003897 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003898#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003899 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003900#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003901 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003902#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003903 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003904
Victor Stinner8c62be82010-05-06 00:08:46 +00003905 if (spawnval == -1)
3906 (void) posix_error();
3907 else
3908 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003909
Victor Stinner8c62be82010-05-06 00:08:46 +00003910 while (--envc >= 0)
3911 PyMem_DEL(envlist[envc]);
3912 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003913 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003914 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003915 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003916 Py_DECREF(opath);
3917 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003918}
3919#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003920#endif /* HAVE_SPAWNV */
3921
3922
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003923#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003924PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003925"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003926Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3927\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003928Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003929
3930static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003931posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003932{
Victor Stinner8c62be82010-05-06 00:08:46 +00003933 pid_t pid;
3934 int result = 0;
3935 _PyImport_AcquireLock();
3936 pid = fork1();
3937 if (pid == 0) {
3938 /* child: this clobbers and resets the import lock. */
3939 PyOS_AfterFork();
3940 } else {
3941 /* parent: release the import lock. */
3942 result = _PyImport_ReleaseLock();
3943 }
3944 if (pid == -1)
3945 return posix_error();
3946 if (result < 0) {
3947 /* Don't clobber the OSError if the fork failed. */
3948 PyErr_SetString(PyExc_RuntimeError,
3949 "not holding the import lock");
3950 return NULL;
3951 }
3952 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003953}
3954#endif
3955
3956
Guido van Rossumad0ee831995-03-01 10:34:45 +00003957#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003958PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003959"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003960Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003961Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003962
Barry Warsaw53699e91996-12-10 23:23:01 +00003963static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003964posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003965{
Victor Stinner8c62be82010-05-06 00:08:46 +00003966 pid_t pid;
3967 int result = 0;
3968 _PyImport_AcquireLock();
3969 pid = fork();
3970 if (pid == 0) {
3971 /* child: this clobbers and resets the import lock. */
3972 PyOS_AfterFork();
3973 } else {
3974 /* parent: release the import lock. */
3975 result = _PyImport_ReleaseLock();
3976 }
3977 if (pid == -1)
3978 return posix_error();
3979 if (result < 0) {
3980 /* Don't clobber the OSError if the fork failed. */
3981 PyErr_SetString(PyExc_RuntimeError,
3982 "not holding the import lock");
3983 return NULL;
3984 }
3985 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003986}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003987#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003988
Neal Norwitzb59798b2003-03-21 01:43:31 +00003989/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003990/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3991#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003992#define DEV_PTY_FILE "/dev/ptc"
3993#define HAVE_DEV_PTMX
3994#else
3995#define DEV_PTY_FILE "/dev/ptmx"
3996#endif
3997
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003998#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003999#ifdef HAVE_PTY_H
4000#include <pty.h>
4001#else
4002#ifdef HAVE_LIBUTIL_H
4003#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00004004#else
4005#ifdef HAVE_UTIL_H
4006#include <util.h>
4007#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004008#endif /* HAVE_LIBUTIL_H */
4009#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00004010#ifdef HAVE_STROPTS_H
4011#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004012#endif
4013#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004014
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004015#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004016PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004017"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004018Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004019
4020static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004021posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004022{
Victor Stinner8c62be82010-05-06 00:08:46 +00004023 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004024#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004025 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004026#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004027#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004028 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004029#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00004030 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004031#endif
4032#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004033
Thomas Wouters70c21a12000-07-14 14:28:33 +00004034#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004035 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4036 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004037#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004038 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4039 if (slave_name == NULL)
4040 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004041
Victor Stinner8c62be82010-05-06 00:08:46 +00004042 slave_fd = open(slave_name, O_RDWR);
4043 if (slave_fd < 0)
4044 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004045#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004046 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4047 if (master_fd < 0)
4048 return posix_error();
4049 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4050 /* change permission of slave */
4051 if (grantpt(master_fd) < 0) {
4052 PyOS_setsig(SIGCHLD, sig_saved);
4053 return posix_error();
4054 }
4055 /* unlock slave */
4056 if (unlockpt(master_fd) < 0) {
4057 PyOS_setsig(SIGCHLD, sig_saved);
4058 return posix_error();
4059 }
4060 PyOS_setsig(SIGCHLD, sig_saved);
4061 slave_name = ptsname(master_fd); /* get name of slave */
4062 if (slave_name == NULL)
4063 return posix_error();
4064 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4065 if (slave_fd < 0)
4066 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004067#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004068 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4069 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004070#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004071 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004072#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004073#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004074#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004075
Victor Stinner8c62be82010-05-06 00:08:46 +00004076 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004077
Fred Drake8cef4cf2000-06-28 16:40:38 +00004078}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004079#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004080
4081#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004082PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004083"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004084Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4085Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004086To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004087
4088static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004089posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004090{
Victor Stinner8c62be82010-05-06 00:08:46 +00004091 int master_fd = -1, result = 0;
4092 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004093
Victor Stinner8c62be82010-05-06 00:08:46 +00004094 _PyImport_AcquireLock();
4095 pid = forkpty(&master_fd, NULL, NULL, NULL);
4096 if (pid == 0) {
4097 /* child: this clobbers and resets the import lock. */
4098 PyOS_AfterFork();
4099 } else {
4100 /* parent: release the import lock. */
4101 result = _PyImport_ReleaseLock();
4102 }
4103 if (pid == -1)
4104 return posix_error();
4105 if (result < 0) {
4106 /* Don't clobber the OSError if the fork failed. */
4107 PyErr_SetString(PyExc_RuntimeError,
4108 "not holding the import lock");
4109 return NULL;
4110 }
4111 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004112}
4113#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004114
Guido van Rossumad0ee831995-03-01 10:34:45 +00004115#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004116PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004117"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004118Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004119
Barry Warsaw53699e91996-12-10 23:23:01 +00004120static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004121posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004122{
Victor Stinner8c62be82010-05-06 00:08:46 +00004123 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004124}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004125#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004126
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004127
Guido van Rossumad0ee831995-03-01 10:34:45 +00004128#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004129PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004130"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004131Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004132
Barry Warsaw53699e91996-12-10 23:23:01 +00004133static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004134posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004135{
Victor Stinner8c62be82010-05-06 00:08:46 +00004136 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004137}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004138#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004139
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004140
Guido van Rossumad0ee831995-03-01 10:34:45 +00004141#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004142PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004143"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004144Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004145
Barry Warsaw53699e91996-12-10 23:23:01 +00004146static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004147posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004148{
Victor Stinner8c62be82010-05-06 00:08:46 +00004149 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004150}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004151#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004152
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004153
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004154PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004155"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004156Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004157
Barry Warsaw53699e91996-12-10 23:23:01 +00004158static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004159posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004160{
Victor Stinner8c62be82010-05-06 00:08:46 +00004161 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004162}
4163
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004164
Fred Drakec9680921999-12-13 16:37:25 +00004165#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004166PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004167"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004168Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004169
4170static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004171posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004172{
4173 PyObject *result = NULL;
4174
Fred Drakec9680921999-12-13 16:37:25 +00004175#ifdef NGROUPS_MAX
4176#define MAX_GROUPS NGROUPS_MAX
4177#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004178 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004179#define MAX_GROUPS 64
4180#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004181 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004182
4183 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
4184 * This is a helper variable to store the intermediate result when
4185 * that happens.
4186 *
4187 * To keep the code readable the OSX behaviour is unconditional,
4188 * according to the POSIX spec this should be safe on all unix-y
4189 * systems.
4190 */
4191 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00004192 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004193
Victor Stinner8c62be82010-05-06 00:08:46 +00004194 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004195 if (n < 0) {
4196 if (errno == EINVAL) {
4197 n = getgroups(0, NULL);
4198 if (n == -1) {
4199 return posix_error();
4200 }
4201 if (n == 0) {
4202 /* Avoid malloc(0) */
4203 alt_grouplist = grouplist;
4204 } else {
4205 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4206 if (alt_grouplist == NULL) {
4207 errno = EINVAL;
4208 return posix_error();
4209 }
4210 n = getgroups(n, alt_grouplist);
4211 if (n == -1) {
4212 PyMem_Free(alt_grouplist);
4213 return posix_error();
4214 }
4215 }
4216 } else {
4217 return posix_error();
4218 }
4219 }
4220 result = PyList_New(n);
4221 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004222 int i;
4223 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004224 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00004225 if (o == NULL) {
4226 Py_DECREF(result);
4227 result = NULL;
4228 break;
Fred Drakec9680921999-12-13 16:37:25 +00004229 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004230 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004231 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004232 }
4233
4234 if (alt_grouplist != grouplist) {
4235 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00004236 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004237
Fred Drakec9680921999-12-13 16:37:25 +00004238 return result;
4239}
4240#endif
4241
Antoine Pitroub7572f02009-12-02 20:46:48 +00004242#ifdef HAVE_INITGROUPS
4243PyDoc_STRVAR(posix_initgroups__doc__,
4244"initgroups(username, gid) -> None\n\n\
4245Call the system initgroups() to initialize the group access list with all of\n\
4246the groups of which the specified username is a member, plus the specified\n\
4247group id.");
4248
4249static PyObject *
4250posix_initgroups(PyObject *self, PyObject *args)
4251{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004252 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00004253 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004254 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004255 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004256
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004257 if (!PyArg_ParseTuple(args, "O&l:initgroups",
4258 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00004259 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004260 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004261
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004262 res = initgroups(username, (gid_t) gid);
4263 Py_DECREF(oname);
4264 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00004265 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004266
Victor Stinner8c62be82010-05-06 00:08:46 +00004267 Py_INCREF(Py_None);
4268 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004269}
4270#endif
4271
Martin v. Löwis606edc12002-06-13 21:09:11 +00004272#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004273PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004274"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004275Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004276
4277static PyObject *
4278posix_getpgid(PyObject *self, PyObject *args)
4279{
Victor Stinner8c62be82010-05-06 00:08:46 +00004280 pid_t pid, pgid;
4281 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4282 return NULL;
4283 pgid = getpgid(pid);
4284 if (pgid < 0)
4285 return posix_error();
4286 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004287}
4288#endif /* HAVE_GETPGID */
4289
4290
Guido van Rossumb6775db1994-08-01 11:34:53 +00004291#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004292PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004293"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004294Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004295
Barry Warsaw53699e91996-12-10 23:23:01 +00004296static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004297posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004298{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004299#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004300 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004301#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004302 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004303#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004304}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004305#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004306
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004307
Guido van Rossumb6775db1994-08-01 11:34:53 +00004308#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004309PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004310"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004311Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004312
Barry Warsaw53699e91996-12-10 23:23:01 +00004313static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004314posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004315{
Guido van Rossum64933891994-10-20 21:56:42 +00004316#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004317 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004318#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004319 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004320#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004321 return posix_error();
4322 Py_INCREF(Py_None);
4323 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004324}
4325
Guido van Rossumb6775db1994-08-01 11:34:53 +00004326#endif /* HAVE_SETPGRP */
4327
Guido van Rossumad0ee831995-03-01 10:34:45 +00004328#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004329
4330#ifdef MS_WINDOWS
4331#include <tlhelp32.h>
4332
4333static PyObject*
4334win32_getppid()
4335{
4336 HANDLE snapshot;
4337 pid_t mypid;
4338 PyObject* result = NULL;
4339 BOOL have_record;
4340 PROCESSENTRY32 pe;
4341
4342 mypid = getpid(); /* This function never fails */
4343
4344 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
4345 if (snapshot == INVALID_HANDLE_VALUE)
4346 return PyErr_SetFromWindowsErr(GetLastError());
4347
4348 pe.dwSize = sizeof(pe);
4349 have_record = Process32First(snapshot, &pe);
4350 while (have_record) {
4351 if (mypid == (pid_t)pe.th32ProcessID) {
4352 /* We could cache the ulong value in a static variable. */
4353 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
4354 break;
4355 }
4356
4357 have_record = Process32Next(snapshot, &pe);
4358 }
4359
4360 /* If our loop exits and our pid was not found (result will be NULL)
4361 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
4362 * error anyway, so let's raise it. */
4363 if (!result)
4364 result = PyErr_SetFromWindowsErr(GetLastError());
4365
4366 CloseHandle(snapshot);
4367
4368 return result;
4369}
4370#endif /*MS_WINDOWS*/
4371
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004372PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004373"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004374Return the parent's process id. If the parent process has already exited,\n\
4375Windows machines will still return its id; others systems will return the id\n\
4376of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004377
Barry Warsaw53699e91996-12-10 23:23:01 +00004378static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004379posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004380{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004381#ifdef MS_WINDOWS
4382 return win32_getppid();
4383#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004384 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00004385#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004386}
4387#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004388
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004389
Fred Drake12c6e2d1999-12-14 21:25:03 +00004390#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004391PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004392"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004393Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004394
4395static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004396posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004397{
Victor Stinner8c62be82010-05-06 00:08:46 +00004398 PyObject *result = NULL;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004399#ifdef MS_WINDOWS
4400 wchar_t user_name[UNLEN + 1];
4401 DWORD num_chars = sizeof(user_name)/sizeof(user_name[0]);
4402
4403 if (GetUserNameW(user_name, &num_chars)) {
4404 /* num_chars is the number of unicode chars plus null terminator */
4405 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
4406 }
4407 else
4408 result = PyErr_SetFromWindowsErr(GetLastError());
4409#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004410 char *name;
4411 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004412
Victor Stinner8c62be82010-05-06 00:08:46 +00004413 errno = 0;
4414 name = getlogin();
4415 if (name == NULL) {
4416 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00004417 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004418 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004419 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00004420 }
4421 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004422 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00004423 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004424#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00004425 return result;
4426}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004427#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00004428
Guido van Rossumad0ee831995-03-01 10:34:45 +00004429#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004430PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004431"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004432Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004433
Barry Warsaw53699e91996-12-10 23:23:01 +00004434static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004435posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004436{
Victor Stinner8c62be82010-05-06 00:08:46 +00004437 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004438}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004439#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004440
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004441
Guido van Rossumad0ee831995-03-01 10:34:45 +00004442#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004443PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004444"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004445Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004446
Barry Warsaw53699e91996-12-10 23:23:01 +00004447static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004448posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004449{
Victor Stinner8c62be82010-05-06 00:08:46 +00004450 pid_t pid;
4451 int sig;
4452 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4453 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004454#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004455 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4456 APIRET rc;
4457 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004458 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004459
4460 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4461 APIRET rc;
4462 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004463 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004464
4465 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004466 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004467#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004468 if (kill(pid, sig) == -1)
4469 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004470#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004471 Py_INCREF(Py_None);
4472 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004473}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004474#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004475
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004476#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004477PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004478"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004479Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004480
4481static PyObject *
4482posix_killpg(PyObject *self, PyObject *args)
4483{
Victor Stinner8c62be82010-05-06 00:08:46 +00004484 int sig;
4485 pid_t pgid;
4486 /* XXX some man pages make the `pgid` parameter an int, others
4487 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4488 take the same type. Moreover, pid_t is always at least as wide as
4489 int (else compilation of this module fails), which is safe. */
4490 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4491 return NULL;
4492 if (killpg(pgid, sig) == -1)
4493 return posix_error();
4494 Py_INCREF(Py_None);
4495 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004496}
4497#endif
4498
Brian Curtineb24d742010-04-12 17:16:38 +00004499#ifdef MS_WINDOWS
4500PyDoc_STRVAR(win32_kill__doc__,
4501"kill(pid, sig)\n\n\
4502Kill a process with a signal.");
4503
4504static PyObject *
4505win32_kill(PyObject *self, PyObject *args)
4506{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004507 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004508 DWORD pid, sig, err;
4509 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004510
Victor Stinner8c62be82010-05-06 00:08:46 +00004511 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4512 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004513
Victor Stinner8c62be82010-05-06 00:08:46 +00004514 /* Console processes which share a common console can be sent CTRL+C or
4515 CTRL+BREAK events, provided they handle said events. */
4516 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4517 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4518 err = GetLastError();
4519 PyErr_SetFromWindowsErr(err);
4520 }
4521 else
4522 Py_RETURN_NONE;
4523 }
Brian Curtineb24d742010-04-12 17:16:38 +00004524
Victor Stinner8c62be82010-05-06 00:08:46 +00004525 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4526 attempt to open and terminate the process. */
4527 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4528 if (handle == NULL) {
4529 err = GetLastError();
4530 return PyErr_SetFromWindowsErr(err);
4531 }
Brian Curtineb24d742010-04-12 17:16:38 +00004532
Victor Stinner8c62be82010-05-06 00:08:46 +00004533 if (TerminateProcess(handle, sig) == 0) {
4534 err = GetLastError();
4535 result = PyErr_SetFromWindowsErr(err);
4536 } else {
4537 Py_INCREF(Py_None);
4538 result = Py_None;
4539 }
Brian Curtineb24d742010-04-12 17:16:38 +00004540
Victor Stinner8c62be82010-05-06 00:08:46 +00004541 CloseHandle(handle);
4542 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004543}
4544#endif /* MS_WINDOWS */
4545
Guido van Rossumc0125471996-06-28 18:55:32 +00004546#ifdef HAVE_PLOCK
4547
4548#ifdef HAVE_SYS_LOCK_H
4549#include <sys/lock.h>
4550#endif
4551
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004552PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004553"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004554Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004555
Barry Warsaw53699e91996-12-10 23:23:01 +00004556static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004557posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004558{
Victor Stinner8c62be82010-05-06 00:08:46 +00004559 int op;
4560 if (!PyArg_ParseTuple(args, "i:plock", &op))
4561 return NULL;
4562 if (plock(op) == -1)
4563 return posix_error();
4564 Py_INCREF(Py_None);
4565 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004566}
4567#endif
4568
Guido van Rossumb6775db1994-08-01 11:34:53 +00004569#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004570PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004571"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004572Set the current process's user id.");
4573
Barry Warsaw53699e91996-12-10 23:23:01 +00004574static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004575posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004576{
Victor Stinner8c62be82010-05-06 00:08:46 +00004577 long uid_arg;
4578 uid_t uid;
4579 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4580 return NULL;
4581 uid = uid_arg;
4582 if (uid != uid_arg) {
4583 PyErr_SetString(PyExc_OverflowError, "user id too big");
4584 return NULL;
4585 }
4586 if (setuid(uid) < 0)
4587 return posix_error();
4588 Py_INCREF(Py_None);
4589 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004590}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004591#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004592
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004593
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004594#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004595PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004596"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004597Set the current process's effective user id.");
4598
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004599static PyObject *
4600posix_seteuid (PyObject *self, PyObject *args)
4601{
Victor Stinner8c62be82010-05-06 00:08:46 +00004602 long euid_arg;
4603 uid_t euid;
4604 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4605 return NULL;
4606 euid = euid_arg;
4607 if (euid != euid_arg) {
4608 PyErr_SetString(PyExc_OverflowError, "user id too big");
4609 return NULL;
4610 }
4611 if (seteuid(euid) < 0) {
4612 return posix_error();
4613 } else {
4614 Py_INCREF(Py_None);
4615 return Py_None;
4616 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004617}
4618#endif /* HAVE_SETEUID */
4619
4620#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004621PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004622"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004623Set the current process's effective group id.");
4624
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004625static PyObject *
4626posix_setegid (PyObject *self, PyObject *args)
4627{
Victor Stinner8c62be82010-05-06 00:08:46 +00004628 long egid_arg;
4629 gid_t egid;
4630 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4631 return NULL;
4632 egid = egid_arg;
4633 if (egid != egid_arg) {
4634 PyErr_SetString(PyExc_OverflowError, "group id too big");
4635 return NULL;
4636 }
4637 if (setegid(egid) < 0) {
4638 return posix_error();
4639 } else {
4640 Py_INCREF(Py_None);
4641 return Py_None;
4642 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004643}
4644#endif /* HAVE_SETEGID */
4645
4646#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004647PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004648"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004649Set the current process's real and effective user ids.");
4650
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004651static PyObject *
4652posix_setreuid (PyObject *self, PyObject *args)
4653{
Victor Stinner8c62be82010-05-06 00:08:46 +00004654 long ruid_arg, euid_arg;
4655 uid_t ruid, euid;
4656 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4657 return NULL;
4658 if (ruid_arg == -1)
4659 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4660 else
4661 ruid = ruid_arg; /* otherwise, assign from our long */
4662 if (euid_arg == -1)
4663 euid = (uid_t)-1;
4664 else
4665 euid = euid_arg;
4666 if ((euid_arg != -1 && euid != euid_arg) ||
4667 (ruid_arg != -1 && ruid != ruid_arg)) {
4668 PyErr_SetString(PyExc_OverflowError, "user id too big");
4669 return NULL;
4670 }
4671 if (setreuid(ruid, euid) < 0) {
4672 return posix_error();
4673 } else {
4674 Py_INCREF(Py_None);
4675 return Py_None;
4676 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004677}
4678#endif /* HAVE_SETREUID */
4679
4680#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004681PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004682"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004683Set the current process's real and effective group ids.");
4684
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004685static PyObject *
4686posix_setregid (PyObject *self, PyObject *args)
4687{
Victor Stinner8c62be82010-05-06 00:08:46 +00004688 long rgid_arg, egid_arg;
4689 gid_t rgid, egid;
4690 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4691 return NULL;
4692 if (rgid_arg == -1)
4693 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4694 else
4695 rgid = rgid_arg; /* otherwise, assign from our long */
4696 if (egid_arg == -1)
4697 egid = (gid_t)-1;
4698 else
4699 egid = egid_arg;
4700 if ((egid_arg != -1 && egid != egid_arg) ||
4701 (rgid_arg != -1 && rgid != rgid_arg)) {
4702 PyErr_SetString(PyExc_OverflowError, "group id too big");
4703 return NULL;
4704 }
4705 if (setregid(rgid, egid) < 0) {
4706 return posix_error();
4707 } else {
4708 Py_INCREF(Py_None);
4709 return Py_None;
4710 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004711}
4712#endif /* HAVE_SETREGID */
4713
Guido van Rossumb6775db1994-08-01 11:34:53 +00004714#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004715PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004716"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004717Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004718
Barry Warsaw53699e91996-12-10 23:23:01 +00004719static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004720posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004721{
Victor Stinner8c62be82010-05-06 00:08:46 +00004722 long gid_arg;
4723 gid_t gid;
4724 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4725 return NULL;
4726 gid = gid_arg;
4727 if (gid != gid_arg) {
4728 PyErr_SetString(PyExc_OverflowError, "group id too big");
4729 return NULL;
4730 }
4731 if (setgid(gid) < 0)
4732 return posix_error();
4733 Py_INCREF(Py_None);
4734 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004735}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004736#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004737
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004738#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004739PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004740"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004741Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004742
4743static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004744posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004745{
Victor Stinner8c62be82010-05-06 00:08:46 +00004746 int i, len;
4747 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004748
Victor Stinner8c62be82010-05-06 00:08:46 +00004749 if (!PySequence_Check(groups)) {
4750 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4751 return NULL;
4752 }
4753 len = PySequence_Size(groups);
4754 if (len > MAX_GROUPS) {
4755 PyErr_SetString(PyExc_ValueError, "too many groups");
4756 return NULL;
4757 }
4758 for(i = 0; i < len; i++) {
4759 PyObject *elem;
4760 elem = PySequence_GetItem(groups, i);
4761 if (!elem)
4762 return NULL;
4763 if (!PyLong_Check(elem)) {
4764 PyErr_SetString(PyExc_TypeError,
4765 "groups must be integers");
4766 Py_DECREF(elem);
4767 return NULL;
4768 } else {
4769 unsigned long x = PyLong_AsUnsignedLong(elem);
4770 if (PyErr_Occurred()) {
4771 PyErr_SetString(PyExc_TypeError,
4772 "group id too big");
4773 Py_DECREF(elem);
4774 return NULL;
4775 }
4776 grouplist[i] = x;
4777 /* read back the value to see if it fitted in gid_t */
4778 if (grouplist[i] != x) {
4779 PyErr_SetString(PyExc_TypeError,
4780 "group id too big");
4781 Py_DECREF(elem);
4782 return NULL;
4783 }
4784 }
4785 Py_DECREF(elem);
4786 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004787
Victor Stinner8c62be82010-05-06 00:08:46 +00004788 if (setgroups(len, grouplist) < 0)
4789 return posix_error();
4790 Py_INCREF(Py_None);
4791 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004792}
4793#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004794
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004795#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4796static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004797wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004798{
Victor Stinner8c62be82010-05-06 00:08:46 +00004799 PyObject *result;
4800 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004801
Victor Stinner8c62be82010-05-06 00:08:46 +00004802 if (pid == -1)
4803 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004804
Victor Stinner8c62be82010-05-06 00:08:46 +00004805 if (struct_rusage == NULL) {
4806 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4807 if (m == NULL)
4808 return NULL;
4809 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4810 Py_DECREF(m);
4811 if (struct_rusage == NULL)
4812 return NULL;
4813 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004814
Victor Stinner8c62be82010-05-06 00:08:46 +00004815 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4816 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4817 if (!result)
4818 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004819
4820#ifndef doubletime
4821#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4822#endif
4823
Victor Stinner8c62be82010-05-06 00:08:46 +00004824 PyStructSequence_SET_ITEM(result, 0,
4825 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4826 PyStructSequence_SET_ITEM(result, 1,
4827 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004828#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004829 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4830 SET_INT(result, 2, ru->ru_maxrss);
4831 SET_INT(result, 3, ru->ru_ixrss);
4832 SET_INT(result, 4, ru->ru_idrss);
4833 SET_INT(result, 5, ru->ru_isrss);
4834 SET_INT(result, 6, ru->ru_minflt);
4835 SET_INT(result, 7, ru->ru_majflt);
4836 SET_INT(result, 8, ru->ru_nswap);
4837 SET_INT(result, 9, ru->ru_inblock);
4838 SET_INT(result, 10, ru->ru_oublock);
4839 SET_INT(result, 11, ru->ru_msgsnd);
4840 SET_INT(result, 12, ru->ru_msgrcv);
4841 SET_INT(result, 13, ru->ru_nsignals);
4842 SET_INT(result, 14, ru->ru_nvcsw);
4843 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004844#undef SET_INT
4845
Victor Stinner8c62be82010-05-06 00:08:46 +00004846 if (PyErr_Occurred()) {
4847 Py_DECREF(result);
4848 return NULL;
4849 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004850
Victor Stinner8c62be82010-05-06 00:08:46 +00004851 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004852}
4853#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4854
4855#ifdef HAVE_WAIT3
4856PyDoc_STRVAR(posix_wait3__doc__,
4857"wait3(options) -> (pid, status, rusage)\n\n\
4858Wait for completion of a child process.");
4859
4860static PyObject *
4861posix_wait3(PyObject *self, PyObject *args)
4862{
Victor Stinner8c62be82010-05-06 00:08:46 +00004863 pid_t pid;
4864 int options;
4865 struct rusage ru;
4866 WAIT_TYPE status;
4867 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004868
Victor Stinner8c62be82010-05-06 00:08:46 +00004869 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4870 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004871
Victor Stinner8c62be82010-05-06 00:08:46 +00004872 Py_BEGIN_ALLOW_THREADS
4873 pid = wait3(&status, options, &ru);
4874 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004875
Victor Stinner8c62be82010-05-06 00:08:46 +00004876 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004877}
4878#endif /* HAVE_WAIT3 */
4879
4880#ifdef HAVE_WAIT4
4881PyDoc_STRVAR(posix_wait4__doc__,
4882"wait4(pid, options) -> (pid, status, rusage)\n\n\
4883Wait for completion of a given child process.");
4884
4885static PyObject *
4886posix_wait4(PyObject *self, PyObject *args)
4887{
Victor Stinner8c62be82010-05-06 00:08:46 +00004888 pid_t pid;
4889 int options;
4890 struct rusage ru;
4891 WAIT_TYPE status;
4892 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004893
Victor Stinner8c62be82010-05-06 00:08:46 +00004894 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
4895 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004896
Victor Stinner8c62be82010-05-06 00:08:46 +00004897 Py_BEGIN_ALLOW_THREADS
4898 pid = wait4(pid, &status, options, &ru);
4899 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004900
Victor Stinner8c62be82010-05-06 00:08:46 +00004901 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004902}
4903#endif /* HAVE_WAIT4 */
4904
Guido van Rossumb6775db1994-08-01 11:34:53 +00004905#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004906PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004907"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004908Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004909
Barry Warsaw53699e91996-12-10 23:23:01 +00004910static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004911posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004912{
Victor Stinner8c62be82010-05-06 00:08:46 +00004913 pid_t pid;
4914 int options;
4915 WAIT_TYPE status;
4916 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004917
Victor Stinner8c62be82010-05-06 00:08:46 +00004918 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4919 return NULL;
4920 Py_BEGIN_ALLOW_THREADS
4921 pid = waitpid(pid, &status, options);
4922 Py_END_ALLOW_THREADS
4923 if (pid == -1)
4924 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004925
Victor Stinner8c62be82010-05-06 00:08:46 +00004926 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004927}
4928
Tim Petersab034fa2002-02-01 11:27:43 +00004929#elif defined(HAVE_CWAIT)
4930
4931/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004932PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004933"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004934"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004935
4936static PyObject *
4937posix_waitpid(PyObject *self, PyObject *args)
4938{
Victor Stinner8c62be82010-05-06 00:08:46 +00004939 Py_intptr_t pid;
4940 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004941
Victor Stinner8c62be82010-05-06 00:08:46 +00004942 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4943 return NULL;
4944 Py_BEGIN_ALLOW_THREADS
4945 pid = _cwait(&status, pid, options);
4946 Py_END_ALLOW_THREADS
4947 if (pid == -1)
4948 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004949
Victor Stinner8c62be82010-05-06 00:08:46 +00004950 /* shift the status left a byte so this is more like the POSIX waitpid */
4951 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004952}
4953#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004954
Guido van Rossumad0ee831995-03-01 10:34:45 +00004955#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004956PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004957"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004958Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004959
Barry Warsaw53699e91996-12-10 23:23:01 +00004960static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004961posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004962{
Victor Stinner8c62be82010-05-06 00:08:46 +00004963 pid_t pid;
4964 WAIT_TYPE status;
4965 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004966
Victor Stinner8c62be82010-05-06 00:08:46 +00004967 Py_BEGIN_ALLOW_THREADS
4968 pid = wait(&status);
4969 Py_END_ALLOW_THREADS
4970 if (pid == -1)
4971 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004972
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004974}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004975#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004976
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004977
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004978PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004979"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004980Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004981
Barry Warsaw53699e91996-12-10 23:23:01 +00004982static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004983posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004984{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004985#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004987#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004988#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00004989 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat",
4990 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004991#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004992 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004993#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004994#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004995}
4996
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004997
Guido van Rossumb6775db1994-08-01 11:34:53 +00004998#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004999PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005000"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005001Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005002
Barry Warsaw53699e91996-12-10 23:23:01 +00005003static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005004posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005005{
Victor Stinner8c62be82010-05-06 00:08:46 +00005006 PyObject* v;
5007 char buf[MAXPATHLEN];
5008 PyObject *opath;
5009 char *path;
5010 int n;
5011 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005012
Victor Stinner8c62be82010-05-06 00:08:46 +00005013 if (!PyArg_ParseTuple(args, "O&:readlink",
5014 PyUnicode_FSConverter, &opath))
5015 return NULL;
5016 path = PyBytes_AsString(opath);
5017 v = PySequence_GetItem(args, 0);
5018 if (v == NULL) {
5019 Py_DECREF(opath);
5020 return NULL;
5021 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00005022
Victor Stinner8c62be82010-05-06 00:08:46 +00005023 if (PyUnicode_Check(v)) {
5024 arg_is_unicode = 1;
5025 }
5026 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005027
Victor Stinner8c62be82010-05-06 00:08:46 +00005028 Py_BEGIN_ALLOW_THREADS
5029 n = readlink(path, buf, (int) sizeof buf);
5030 Py_END_ALLOW_THREADS
5031 if (n < 0)
5032 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005033
Victor Stinner8c62be82010-05-06 00:08:46 +00005034 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00005035 if (arg_is_unicode)
5036 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
5037 else
5038 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005039}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005040#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005041
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005042
Guido van Rossumb6775db1994-08-01 11:34:53 +00005043#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005044PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005045"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005046Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005047
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005048static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005049posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005050{
Victor Stinner8c62be82010-05-06 00:08:46 +00005051 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005052}
5053#endif /* HAVE_SYMLINK */
5054
Brian Curtind40e6f72010-07-08 21:39:08 +00005055#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
5056
5057PyDoc_STRVAR(win_readlink__doc__,
5058"readlink(path) -> path\n\n\
5059Return a string representing the path to which the symbolic link points.");
5060
Brian Curtind40e6f72010-07-08 21:39:08 +00005061/* Windows readlink implementation */
5062static PyObject *
5063win_readlink(PyObject *self, PyObject *args)
5064{
5065 wchar_t *path;
5066 DWORD n_bytes_returned;
5067 DWORD io_result;
5068 PyObject *result;
5069 HANDLE reparse_point_handle;
5070
5071 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
5072 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
5073 wchar_t *print_name;
5074
5075 if (!PyArg_ParseTuple(args,
5076 "u:readlink",
5077 &path))
5078 return NULL;
5079
5080 /* First get a handle to the reparse point */
5081 Py_BEGIN_ALLOW_THREADS
5082 reparse_point_handle = CreateFileW(
5083 path,
5084 0,
5085 0,
5086 0,
5087 OPEN_EXISTING,
5088 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
5089 0);
5090 Py_END_ALLOW_THREADS
5091
5092 if (reparse_point_handle==INVALID_HANDLE_VALUE)
5093 {
5094 return win32_error_unicode("readlink", path);
5095 }
5096
5097 Py_BEGIN_ALLOW_THREADS
5098 /* New call DeviceIoControl to read the reparse point */
5099 io_result = DeviceIoControl(
5100 reparse_point_handle,
5101 FSCTL_GET_REPARSE_POINT,
5102 0, 0, /* in buffer */
5103 target_buffer, sizeof(target_buffer),
5104 &n_bytes_returned,
5105 0 /* we're not using OVERLAPPED_IO */
5106 );
5107 CloseHandle(reparse_point_handle);
5108 Py_END_ALLOW_THREADS
5109
5110 if (io_result==0)
5111 {
5112 return win32_error_unicode("readlink", path);
5113 }
5114
5115 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5116 {
5117 PyErr_SetString(PyExc_ValueError,
5118 "not a symbolic link");
5119 return NULL;
5120 }
Brian Curtin74e45612010-07-09 15:58:59 +00005121 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
5122 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5123
5124 result = PyUnicode_FromWideChar(print_name,
5125 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00005126 return result;
5127}
5128
5129#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5130
5131#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
5132
5133/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5134static int has_CreateSymbolicLinkW = 0;
5135static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5136static int
5137check_CreateSymbolicLinkW()
5138{
5139 HINSTANCE hKernel32;
5140 /* only recheck */
5141 if (has_CreateSymbolicLinkW)
5142 return has_CreateSymbolicLinkW;
5143 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00005144 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
5145 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00005146 if (Py_CreateSymbolicLinkW)
5147 has_CreateSymbolicLinkW = 1;
5148 return has_CreateSymbolicLinkW;
5149}
5150
5151PyDoc_STRVAR(win_symlink__doc__,
5152"symlink(src, dst, target_is_directory=False)\n\n\
5153Create a symbolic link pointing to src named dst.\n\
5154target_is_directory is required if the target is to be interpreted as\n\
5155a directory.\n\
5156This function requires Windows 6.0 or greater, and raises a\n\
5157NotImplementedError otherwise.");
5158
5159static PyObject *
5160win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5161{
5162 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5163 PyObject *src, *dest;
5164 int target_is_directory = 0;
5165 DWORD res;
5166 WIN32_FILE_ATTRIBUTE_DATA src_info;
5167
5168 if (!check_CreateSymbolicLinkW())
5169 {
5170 /* raise NotImplementedError */
5171 return PyErr_Format(PyExc_NotImplementedError,
5172 "CreateSymbolicLinkW not found");
5173 }
5174 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5175 kwlist, &src, &dest, &target_is_directory))
5176 return NULL;
5177 if (!convert_to_unicode(&src)) { return NULL; }
5178 if (!convert_to_unicode(&dest)) {
5179 Py_DECREF(src);
5180 return NULL;
5181 }
5182
5183 /* if src is a directory, ensure target_is_directory==1 */
5184 if(
5185 GetFileAttributesExW(
5186 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5187 ))
5188 {
5189 target_is_directory = target_is_directory ||
5190 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5191 }
5192
5193 Py_BEGIN_ALLOW_THREADS
5194 res = Py_CreateSymbolicLinkW(
5195 PyUnicode_AsUnicode(dest),
5196 PyUnicode_AsUnicode(src),
5197 target_is_directory);
5198 Py_END_ALLOW_THREADS
5199 Py_DECREF(src);
5200 Py_DECREF(dest);
5201 if (!res)
5202 {
5203 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5204 }
5205
5206 Py_INCREF(Py_None);
5207 return Py_None;
5208}
5209#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005210
5211#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005212#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5213static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005214system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005215{
5216 ULONG value = 0;
5217
5218 Py_BEGIN_ALLOW_THREADS
5219 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5220 Py_END_ALLOW_THREADS
5221
5222 return value;
5223}
5224
5225static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005226posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005227{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005228 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005229 return Py_BuildValue("ddddd",
5230 (double)0 /* t.tms_utime / HZ */,
5231 (double)0 /* t.tms_stime / HZ */,
5232 (double)0 /* t.tms_cutime / HZ */,
5233 (double)0 /* t.tms_cstime / HZ */,
5234 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005235}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005236#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005237#define NEED_TICKS_PER_SECOND
5238static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005239static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005240posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005241{
Victor Stinner8c62be82010-05-06 00:08:46 +00005242 struct tms t;
5243 clock_t c;
5244 errno = 0;
5245 c = times(&t);
5246 if (c == (clock_t) -1)
5247 return posix_error();
5248 return Py_BuildValue("ddddd",
5249 (double)t.tms_utime / ticks_per_second,
5250 (double)t.tms_stime / ticks_per_second,
5251 (double)t.tms_cutime / ticks_per_second,
5252 (double)t.tms_cstime / ticks_per_second,
5253 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005254}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005255#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005256#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005257
5258
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005259#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005260#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005261static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005262posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005263{
Victor Stinner8c62be82010-05-06 00:08:46 +00005264 FILETIME create, exit, kernel, user;
5265 HANDLE hProc;
5266 hProc = GetCurrentProcess();
5267 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5268 /* The fields of a FILETIME structure are the hi and lo part
5269 of a 64-bit value expressed in 100 nanosecond units.
5270 1e7 is one second in such units; 1e-7 the inverse.
5271 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5272 */
5273 return Py_BuildValue(
5274 "ddddd",
5275 (double)(user.dwHighDateTime*429.4967296 +
5276 user.dwLowDateTime*1e-7),
5277 (double)(kernel.dwHighDateTime*429.4967296 +
5278 kernel.dwLowDateTime*1e-7),
5279 (double)0,
5280 (double)0,
5281 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005282}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005283#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005284
5285#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005286PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005287"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005288Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005289#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005290
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005291
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005292#ifdef HAVE_GETSID
5293PyDoc_STRVAR(posix_getsid__doc__,
5294"getsid(pid) -> sid\n\n\
5295Call the system call getsid().");
5296
5297static PyObject *
5298posix_getsid(PyObject *self, PyObject *args)
5299{
Victor Stinner8c62be82010-05-06 00:08:46 +00005300 pid_t pid;
5301 int sid;
5302 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5303 return NULL;
5304 sid = getsid(pid);
5305 if (sid < 0)
5306 return posix_error();
5307 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005308}
5309#endif /* HAVE_GETSID */
5310
5311
Guido van Rossumb6775db1994-08-01 11:34:53 +00005312#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005313PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005314"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005315Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005316
Barry Warsaw53699e91996-12-10 23:23:01 +00005317static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005318posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005319{
Victor Stinner8c62be82010-05-06 00:08:46 +00005320 if (setsid() < 0)
5321 return posix_error();
5322 Py_INCREF(Py_None);
5323 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005324}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005325#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005326
Guido van Rossumb6775db1994-08-01 11:34:53 +00005327#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005328PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005329"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005330Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005331
Barry Warsaw53699e91996-12-10 23:23:01 +00005332static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005333posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005334{
Victor Stinner8c62be82010-05-06 00:08:46 +00005335 pid_t pid;
5336 int pgrp;
5337 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5338 return NULL;
5339 if (setpgid(pid, pgrp) < 0)
5340 return posix_error();
5341 Py_INCREF(Py_None);
5342 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005343}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005344#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005346
Guido van Rossumb6775db1994-08-01 11:34:53 +00005347#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005348PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005349"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005350Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005351
Barry Warsaw53699e91996-12-10 23:23:01 +00005352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005353posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005354{
Victor Stinner8c62be82010-05-06 00:08:46 +00005355 int fd;
5356 pid_t pgid;
5357 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5358 return NULL;
5359 pgid = tcgetpgrp(fd);
5360 if (pgid < 0)
5361 return posix_error();
5362 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005363}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005364#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005365
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005366
Guido van Rossumb6775db1994-08-01 11:34:53 +00005367#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005368PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005369"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005370Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005371
Barry Warsaw53699e91996-12-10 23:23:01 +00005372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005373posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005374{
Victor Stinner8c62be82010-05-06 00:08:46 +00005375 int fd;
5376 pid_t pgid;
5377 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5378 return NULL;
5379 if (tcsetpgrp(fd, pgid) < 0)
5380 return posix_error();
5381 Py_INCREF(Py_None);
5382 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005383}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005384#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005385
Guido van Rossum687dd131993-05-17 08:34:16 +00005386/* Functions acting on file descriptors */
5387
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005388PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005389"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005390Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005391
Barry Warsaw53699e91996-12-10 23:23:01 +00005392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005393posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005394{
Victor Stinner8c62be82010-05-06 00:08:46 +00005395 PyObject *ofile;
5396 char *file;
5397 int flag;
5398 int mode = 0777;
5399 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005400
5401#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005402 PyUnicodeObject *po;
5403 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5404 Py_BEGIN_ALLOW_THREADS
5405 /* PyUnicode_AS_UNICODE OK without thread
5406 lock as it is a simple dereference. */
5407 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5408 Py_END_ALLOW_THREADS
5409 if (fd < 0)
5410 return posix_error();
5411 return PyLong_FromLong((long)fd);
5412 }
5413 /* Drop the argument parsing error as narrow strings
5414 are also valid. */
5415 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005416#endif
5417
Victor Stinner8c62be82010-05-06 00:08:46 +00005418 if (!PyArg_ParseTuple(args, "O&i|i",
5419 PyUnicode_FSConverter, &ofile,
5420 &flag, &mode))
5421 return NULL;
5422 file = PyBytes_AsString(ofile);
5423 Py_BEGIN_ALLOW_THREADS
5424 fd = open(file, flag, mode);
5425 Py_END_ALLOW_THREADS
5426 if (fd < 0)
5427 return posix_error_with_allocated_filename(ofile);
5428 Py_DECREF(ofile);
5429 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005430}
5431
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005432
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005433PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005434"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005435Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005436
Barry Warsaw53699e91996-12-10 23:23:01 +00005437static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005438posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005439{
Victor Stinner8c62be82010-05-06 00:08:46 +00005440 int fd, res;
5441 if (!PyArg_ParseTuple(args, "i:close", &fd))
5442 return NULL;
5443 if (!_PyVerify_fd(fd))
5444 return posix_error();
5445 Py_BEGIN_ALLOW_THREADS
5446 res = close(fd);
5447 Py_END_ALLOW_THREADS
5448 if (res < 0)
5449 return posix_error();
5450 Py_INCREF(Py_None);
5451 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005452}
5453
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005454
Victor Stinner8c62be82010-05-06 00:08:46 +00005455PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005456"closerange(fd_low, fd_high)\n\n\
5457Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5458
5459static PyObject *
5460posix_closerange(PyObject *self, PyObject *args)
5461{
Victor Stinner8c62be82010-05-06 00:08:46 +00005462 int fd_from, fd_to, i;
5463 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5464 return NULL;
5465 Py_BEGIN_ALLOW_THREADS
5466 for (i = fd_from; i < fd_to; i++)
5467 if (_PyVerify_fd(i))
5468 close(i);
5469 Py_END_ALLOW_THREADS
5470 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005471}
5472
5473
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005474PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005475"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005476Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005477
Barry Warsaw53699e91996-12-10 23:23:01 +00005478static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005479posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005480{
Victor Stinner8c62be82010-05-06 00:08:46 +00005481 int fd;
5482 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5483 return NULL;
5484 if (!_PyVerify_fd(fd))
5485 return posix_error();
5486 Py_BEGIN_ALLOW_THREADS
5487 fd = dup(fd);
5488 Py_END_ALLOW_THREADS
5489 if (fd < 0)
5490 return posix_error();
5491 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005492}
5493
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005494
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005495PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005496"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005497Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005498
Barry Warsaw53699e91996-12-10 23:23:01 +00005499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005500posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005501{
Victor Stinner8c62be82010-05-06 00:08:46 +00005502 int fd, fd2, res;
5503 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5504 return NULL;
5505 if (!_PyVerify_fd_dup2(fd, fd2))
5506 return posix_error();
5507 Py_BEGIN_ALLOW_THREADS
5508 res = dup2(fd, fd2);
5509 Py_END_ALLOW_THREADS
5510 if (res < 0)
5511 return posix_error();
5512 Py_INCREF(Py_None);
5513 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005514}
5515
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005516
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005517PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005518"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005519Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005520
Barry Warsaw53699e91996-12-10 23:23:01 +00005521static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005522posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005523{
Victor Stinner8c62be82010-05-06 00:08:46 +00005524 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005525#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005526 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005527#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005528 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005529#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005530 PyObject *posobj;
5531 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5532 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005533#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005534 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5535 switch (how) {
5536 case 0: how = SEEK_SET; break;
5537 case 1: how = SEEK_CUR; break;
5538 case 2: how = SEEK_END; break;
5539 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005540#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005541
5542#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005543 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005544#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005545 pos = PyLong_Check(posobj) ?
5546 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005547#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005548 if (PyErr_Occurred())
5549 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005550
Victor Stinner8c62be82010-05-06 00:08:46 +00005551 if (!_PyVerify_fd(fd))
5552 return posix_error();
5553 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005554#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005555 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005556#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005557 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005558#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005559 Py_END_ALLOW_THREADS
5560 if (res < 0)
5561 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005562
5563#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005564 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005565#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005566 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005567#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005568}
5569
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005570
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005571PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005572"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005573Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005574
Barry Warsaw53699e91996-12-10 23:23:01 +00005575static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005576posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005577{
Victor Stinner8c62be82010-05-06 00:08:46 +00005578 int fd, size;
5579 Py_ssize_t n;
5580 PyObject *buffer;
5581 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5582 return NULL;
5583 if (size < 0) {
5584 errno = EINVAL;
5585 return posix_error();
5586 }
5587 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5588 if (buffer == NULL)
5589 return NULL;
5590 if (!_PyVerify_fd(fd))
5591 return posix_error();
5592 Py_BEGIN_ALLOW_THREADS
5593 n = read(fd, PyBytes_AS_STRING(buffer), size);
5594 Py_END_ALLOW_THREADS
5595 if (n < 0) {
5596 Py_DECREF(buffer);
5597 return posix_error();
5598 }
5599 if (n != size)
5600 _PyBytes_Resize(&buffer, n);
5601 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005602}
5603
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005604
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005605PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005606"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005607Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005608
Barry Warsaw53699e91996-12-10 23:23:01 +00005609static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005610posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005611{
Victor Stinner8c62be82010-05-06 00:08:46 +00005612 Py_buffer pbuf;
5613 int fd;
5614 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005615
Victor Stinner8c62be82010-05-06 00:08:46 +00005616 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5617 return NULL;
5618 if (!_PyVerify_fd(fd))
5619 return posix_error();
5620 Py_BEGIN_ALLOW_THREADS
5621 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5622 Py_END_ALLOW_THREADS
5623 PyBuffer_Release(&pbuf);
5624 if (size < 0)
5625 return posix_error();
5626 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005627}
5628
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005629
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005630PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005631"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005632Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005633
Barry Warsaw53699e91996-12-10 23:23:01 +00005634static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005635posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005636{
Victor Stinner8c62be82010-05-06 00:08:46 +00005637 int fd;
5638 STRUCT_STAT st;
5639 int res;
5640 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5641 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005642#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005643 /* on OpenVMS we must ensure that all bytes are written to the file */
5644 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005645#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005646 if (!_PyVerify_fd(fd))
5647 return posix_error();
5648 Py_BEGIN_ALLOW_THREADS
5649 res = FSTAT(fd, &st);
5650 Py_END_ALLOW_THREADS
5651 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005652#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005653 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005654#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005655 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005656#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005657 }
Tim Peters5aa91602002-01-30 05:46:57 +00005658
Victor Stinner8c62be82010-05-06 00:08:46 +00005659 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005660}
5661
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005662PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005663"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005664Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005665connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005666
5667static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005668posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005669{
Victor Stinner8c62be82010-05-06 00:08:46 +00005670 int fd;
5671 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5672 return NULL;
5673 if (!_PyVerify_fd(fd))
5674 return PyBool_FromLong(0);
5675 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005676}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005677
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005678#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005679PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005680"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005681Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005682
Barry Warsaw53699e91996-12-10 23:23:01 +00005683static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005684posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005685{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005686#if defined(PYOS_OS2)
5687 HFILE read, write;
5688 APIRET rc;
5689
Victor Stinner8c62be82010-05-06 00:08:46 +00005690 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005691 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005692 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005693 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005694 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005695
5696 return Py_BuildValue("(ii)", read, write);
5697#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005698#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005699 int fds[2];
5700 int res;
5701 Py_BEGIN_ALLOW_THREADS
5702 res = pipe(fds);
5703 Py_END_ALLOW_THREADS
5704 if (res != 0)
5705 return posix_error();
5706 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005707#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00005708 HANDLE read, write;
5709 int read_fd, write_fd;
5710 BOOL ok;
5711 Py_BEGIN_ALLOW_THREADS
5712 ok = CreatePipe(&read, &write, NULL, 0);
5713 Py_END_ALLOW_THREADS
5714 if (!ok)
5715 return win32_error("CreatePipe", NULL);
5716 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5717 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5718 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005719#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005720#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005721}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005722#endif /* HAVE_PIPE */
5723
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005724
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005725#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005726PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005727"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005728Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005729
Barry Warsaw53699e91996-12-10 23:23:01 +00005730static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005731posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005732{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005733 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005734 char *filename;
5735 int mode = 0666;
5736 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005737 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5738 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00005739 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005740 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005741 Py_BEGIN_ALLOW_THREADS
5742 res = mkfifo(filename, mode);
5743 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005744 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005745 if (res < 0)
5746 return posix_error();
5747 Py_INCREF(Py_None);
5748 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005749}
5750#endif
5751
5752
Neal Norwitz11690112002-07-30 01:08:28 +00005753#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005754PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005755"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005756Create a filesystem node (file, device special file or named pipe)\n\
5757named filename. mode specifies both the permissions to use and the\n\
5758type of node to be created, being combined (bitwise OR) with one of\n\
5759S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005760device defines the newly created device special file (probably using\n\
5761os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005762
5763
5764static PyObject *
5765posix_mknod(PyObject *self, PyObject *args)
5766{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005767 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005768 char *filename;
5769 int mode = 0600;
5770 int device = 0;
5771 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005772 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5773 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00005774 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005775 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005776 Py_BEGIN_ALLOW_THREADS
5777 res = mknod(filename, mode, device);
5778 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005779 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005780 if (res < 0)
5781 return posix_error();
5782 Py_INCREF(Py_None);
5783 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005784}
5785#endif
5786
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005787#ifdef HAVE_DEVICE_MACROS
5788PyDoc_STRVAR(posix_major__doc__,
5789"major(device) -> major number\n\
5790Extracts a device major number from a raw device number.");
5791
5792static PyObject *
5793posix_major(PyObject *self, PyObject *args)
5794{
Victor Stinner8c62be82010-05-06 00:08:46 +00005795 int device;
5796 if (!PyArg_ParseTuple(args, "i:major", &device))
5797 return NULL;
5798 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005799}
5800
5801PyDoc_STRVAR(posix_minor__doc__,
5802"minor(device) -> minor number\n\
5803Extracts a device minor number from a raw device number.");
5804
5805static PyObject *
5806posix_minor(PyObject *self, PyObject *args)
5807{
Victor Stinner8c62be82010-05-06 00:08:46 +00005808 int device;
5809 if (!PyArg_ParseTuple(args, "i:minor", &device))
5810 return NULL;
5811 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005812}
5813
5814PyDoc_STRVAR(posix_makedev__doc__,
5815"makedev(major, minor) -> device number\n\
5816Composes a raw device number from the major and minor device numbers.");
5817
5818static PyObject *
5819posix_makedev(PyObject *self, PyObject *args)
5820{
Victor Stinner8c62be82010-05-06 00:08:46 +00005821 int major, minor;
5822 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5823 return NULL;
5824 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005825}
5826#endif /* device macros */
5827
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005828
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005829#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005830PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005831"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005832Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005833
Barry Warsaw53699e91996-12-10 23:23:01 +00005834static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005835posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005836{
Victor Stinner8c62be82010-05-06 00:08:46 +00005837 int fd;
5838 off_t length;
5839 int res;
5840 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005841
Victor Stinner8c62be82010-05-06 00:08:46 +00005842 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5843 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005844
5845#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005846 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005847#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005848 length = PyLong_Check(lenobj) ?
5849 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005850#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005851 if (PyErr_Occurred())
5852 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005853
Victor Stinner8c62be82010-05-06 00:08:46 +00005854 Py_BEGIN_ALLOW_THREADS
5855 res = ftruncate(fd, length);
5856 Py_END_ALLOW_THREADS
5857 if (res < 0)
5858 return posix_error();
5859 Py_INCREF(Py_None);
5860 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005861}
5862#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005863
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005864#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005865PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005866"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005867Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005868
Fred Drake762e2061999-08-26 17:23:54 +00005869/* Save putenv() parameters as values here, so we can collect them when they
5870 * get re-set with another call for the same key. */
5871static PyObject *posix_putenv_garbage;
5872
Tim Peters5aa91602002-01-30 05:46:57 +00005873static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005874posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005875{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005876#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005877 wchar_t *s1, *s2;
5878 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005879#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005880 PyObject *os1, *os2;
5881 char *s1, *s2;
5882 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005883#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005884 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005885 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005886
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005887#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005888 if (!PyArg_ParseTuple(args,
5889 "uu:putenv",
5890 &s1, &s2))
5891 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005892#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005893 if (!PyArg_ParseTuple(args,
5894 "O&O&:putenv",
5895 PyUnicode_FSConverter, &os1,
5896 PyUnicode_FSConverter, &os2))
5897 return NULL;
5898 s1 = PyBytes_AsString(os1);
5899 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005900#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005901
5902#if defined(PYOS_OS2)
5903 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5904 APIRET rc;
5905
Guido van Rossumd48f2521997-12-05 22:19:34 +00005906 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005907 if (rc != NO_ERROR) {
5908 os2_error(rc);
5909 goto error;
5910 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005911
5912 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5913 APIRET rc;
5914
Guido van Rossumd48f2521997-12-05 22:19:34 +00005915 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005916 if (rc != NO_ERROR) {
5917 os2_error(rc);
5918 goto error;
5919 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005920 } else {
5921#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005922 /* XXX This can leak memory -- not easy to fix :-( */
5923 /* len includes space for a trailing \0; the size arg to
5924 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005925#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005926 len = wcslen(s1) + wcslen(s2) + 2;
5927 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005928#else
Victor Stinner84ae1182010-05-06 22:05:07 +00005929 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00005930 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005931#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005932 if (newstr == NULL) {
5933 PyErr_NoMemory();
5934 goto error;
5935 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005936#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005937 newenv = PyUnicode_AsUnicode(newstr);
5938 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5939 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005940 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005941 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005942 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005943#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005944 newenv = PyBytes_AS_STRING(newstr);
5945 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5946 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005947 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005948 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005949 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005950#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005951
Victor Stinner8c62be82010-05-06 00:08:46 +00005952 /* Install the first arg and newstr in posix_putenv_garbage;
5953 * this will cause previous value to be collected. This has to
5954 * happen after the real putenv() call because the old value
5955 * was still accessible until then. */
5956 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00005957#ifdef MS_WINDOWS
5958 PyTuple_GET_ITEM(args, 0),
5959#else
5960 os1,
5961#endif
5962 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005963 /* really not much we can do; just leak */
5964 PyErr_Clear();
5965 }
5966 else {
5967 Py_DECREF(newstr);
5968 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005969
5970#if defined(PYOS_OS2)
5971 }
5972#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005973
Martin v. Löwis011e8422009-05-05 04:43:17 +00005974#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005975 Py_DECREF(os1);
5976 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005977#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005978 Py_RETURN_NONE;
5979
5980error:
5981#ifndef MS_WINDOWS
5982 Py_DECREF(os1);
5983 Py_DECREF(os2);
5984#endif
5985 Py_XDECREF(newstr);
5986 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005987}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005988#endif /* putenv */
5989
Guido van Rossumc524d952001-10-19 01:31:59 +00005990#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005991PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005992"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005993Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005994
5995static PyObject *
5996posix_unsetenv(PyObject *self, PyObject *args)
5997{
Victor Stinner84ae1182010-05-06 22:05:07 +00005998#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005999 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006000
Victor Stinner8c62be82010-05-06 00:08:46 +00006001 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6002 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00006003#else
6004 PyObject *os1;
6005 char *s1;
6006
6007 if (!PyArg_ParseTuple(args, "O&:unsetenv",
6008 PyUnicode_FSConverter, &os1))
6009 return NULL;
6010 s1 = PyBytes_AsString(os1);
6011#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006012
Victor Stinner8c62be82010-05-06 00:08:46 +00006013 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006014
Victor Stinner8c62be82010-05-06 00:08:46 +00006015 /* Remove the key from posix_putenv_garbage;
6016 * this will cause it to be collected. This has to
6017 * happen after the real unsetenv() call because the
6018 * old value was still accessible until then.
6019 */
6020 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006021#ifdef MS_WINDOWS
6022 PyTuple_GET_ITEM(args, 0)
6023#else
6024 os1
6025#endif
6026 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006027 /* really not much we can do; just leak */
6028 PyErr_Clear();
6029 }
Guido van Rossumc524d952001-10-19 01:31:59 +00006030
Victor Stinner84ae1182010-05-06 22:05:07 +00006031#ifndef MS_WINDOWS
6032 Py_DECREF(os1);
6033#endif
6034 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00006035}
6036#endif /* unsetenv */
6037
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006038PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006039"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006040Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006041
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006043posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006044{
Victor Stinner8c62be82010-05-06 00:08:46 +00006045 int code;
6046 char *message;
6047 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6048 return NULL;
6049 message = strerror(code);
6050 if (message == NULL) {
6051 PyErr_SetString(PyExc_ValueError,
6052 "strerror() argument out of range");
6053 return NULL;
6054 }
6055 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006056}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006057
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006058
Guido van Rossumc9641791998-08-04 15:26:23 +00006059#ifdef HAVE_SYS_WAIT_H
6060
Fred Drake106c1a02002-04-23 15:58:02 +00006061#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006062PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006063"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006064Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006065
6066static PyObject *
6067posix_WCOREDUMP(PyObject *self, PyObject *args)
6068{
Victor Stinner8c62be82010-05-06 00:08:46 +00006069 WAIT_TYPE status;
6070 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006071
Victor Stinner8c62be82010-05-06 00:08:46 +00006072 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6073 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006074
Victor Stinner8c62be82010-05-06 00:08:46 +00006075 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006076}
6077#endif /* WCOREDUMP */
6078
6079#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006080PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006081"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006082Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006083job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006084
6085static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006086posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006087{
Victor Stinner8c62be82010-05-06 00:08:46 +00006088 WAIT_TYPE status;
6089 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006090
Victor Stinner8c62be82010-05-06 00:08:46 +00006091 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6092 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006093
Victor Stinner8c62be82010-05-06 00:08:46 +00006094 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006095}
6096#endif /* WIFCONTINUED */
6097
Guido van Rossumc9641791998-08-04 15:26:23 +00006098#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006099PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006100"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006101Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006102
6103static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006104posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006105{
Victor Stinner8c62be82010-05-06 00:08:46 +00006106 WAIT_TYPE status;
6107 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006108
Victor Stinner8c62be82010-05-06 00:08:46 +00006109 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6110 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006111
Victor Stinner8c62be82010-05-06 00:08:46 +00006112 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006113}
6114#endif /* WIFSTOPPED */
6115
6116#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006117PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006118"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006119Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006120
6121static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006122posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006123{
Victor Stinner8c62be82010-05-06 00:08:46 +00006124 WAIT_TYPE status;
6125 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006126
Victor Stinner8c62be82010-05-06 00:08:46 +00006127 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6128 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006129
Victor Stinner8c62be82010-05-06 00:08:46 +00006130 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006131}
6132#endif /* WIFSIGNALED */
6133
6134#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006135PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006136"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006137Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006138system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006139
6140static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006141posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006142{
Victor Stinner8c62be82010-05-06 00:08:46 +00006143 WAIT_TYPE status;
6144 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006145
Victor Stinner8c62be82010-05-06 00:08:46 +00006146 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6147 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006148
Victor Stinner8c62be82010-05-06 00:08:46 +00006149 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006150}
6151#endif /* WIFEXITED */
6152
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006153#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006154PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006155"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006156Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006157
6158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006159posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006160{
Victor Stinner8c62be82010-05-06 00:08:46 +00006161 WAIT_TYPE status;
6162 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006163
Victor Stinner8c62be82010-05-06 00:08:46 +00006164 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6165 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006166
Victor Stinner8c62be82010-05-06 00:08:46 +00006167 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006168}
6169#endif /* WEXITSTATUS */
6170
6171#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006172PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006173"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006174Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006175value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006176
6177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006178posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006179{
Victor Stinner8c62be82010-05-06 00:08:46 +00006180 WAIT_TYPE status;
6181 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006182
Victor Stinner8c62be82010-05-06 00:08:46 +00006183 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6184 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006185
Victor Stinner8c62be82010-05-06 00:08:46 +00006186 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006187}
6188#endif /* WTERMSIG */
6189
6190#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006191PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006192"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006193Return the signal that stopped the process that provided\n\
6194the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006195
6196static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006197posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006198{
Victor Stinner8c62be82010-05-06 00:08:46 +00006199 WAIT_TYPE status;
6200 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006201
Victor Stinner8c62be82010-05-06 00:08:46 +00006202 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6203 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006204
Victor Stinner8c62be82010-05-06 00:08:46 +00006205 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006206}
6207#endif /* WSTOPSIG */
6208
6209#endif /* HAVE_SYS_WAIT_H */
6210
6211
Thomas Wouters477c8d52006-05-27 19:21:47 +00006212#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006213#ifdef _SCO_DS
6214/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6215 needed definitions in sys/statvfs.h */
6216#define _SVID3
6217#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006218#include <sys/statvfs.h>
6219
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006220static PyObject*
6221_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006222 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6223 if (v == NULL)
6224 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006225
6226#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006227 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6228 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6229 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6230 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6231 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6232 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6233 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6234 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6235 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6236 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006237#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006238 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6239 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6240 PyStructSequence_SET_ITEM(v, 2,
6241 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6242 PyStructSequence_SET_ITEM(v, 3,
6243 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6244 PyStructSequence_SET_ITEM(v, 4,
6245 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6246 PyStructSequence_SET_ITEM(v, 5,
6247 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6248 PyStructSequence_SET_ITEM(v, 6,
6249 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6250 PyStructSequence_SET_ITEM(v, 7,
6251 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6252 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6253 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006254#endif
6255
Victor Stinner8c62be82010-05-06 00:08:46 +00006256 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006257}
6258
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006259PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006260"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006261Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006262
6263static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006264posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006265{
Victor Stinner8c62be82010-05-06 00:08:46 +00006266 int fd, res;
6267 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006268
Victor Stinner8c62be82010-05-06 00:08:46 +00006269 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6270 return NULL;
6271 Py_BEGIN_ALLOW_THREADS
6272 res = fstatvfs(fd, &st);
6273 Py_END_ALLOW_THREADS
6274 if (res != 0)
6275 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006276
Victor Stinner8c62be82010-05-06 00:08:46 +00006277 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006278}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006279#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006280
6281
Thomas Wouters477c8d52006-05-27 19:21:47 +00006282#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006283#include <sys/statvfs.h>
6284
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006285PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006286"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006287Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006288
6289static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006290posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006291{
Victor Stinner8c62be82010-05-06 00:08:46 +00006292 char *path;
6293 int res;
6294 struct statvfs st;
6295 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6296 return NULL;
6297 Py_BEGIN_ALLOW_THREADS
6298 res = statvfs(path, &st);
6299 Py_END_ALLOW_THREADS
6300 if (res != 0)
6301 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006302
Victor Stinner8c62be82010-05-06 00:08:46 +00006303 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006304}
6305#endif /* HAVE_STATVFS */
6306
Fred Drakec9680921999-12-13 16:37:25 +00006307/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6308 * It maps strings representing configuration variable names to
6309 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006310 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006311 * rarely-used constants. There are three separate tables that use
6312 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006313 *
6314 * This code is always included, even if none of the interfaces that
6315 * need it are included. The #if hackery needed to avoid it would be
6316 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006317 */
6318struct constdef {
6319 char *name;
6320 long value;
6321};
6322
Fred Drake12c6e2d1999-12-14 21:25:03 +00006323static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006324conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006325 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006326{
Christian Heimes217cfd12007-12-02 14:31:20 +00006327 if (PyLong_Check(arg)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006328 *valuep = PyLong_AS_LONG(arg);
6329 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006330 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006331 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00006332 /* look up the value in the table using a binary search */
6333 size_t lo = 0;
6334 size_t mid;
6335 size_t hi = tablesize;
6336 int cmp;
6337 const char *confname;
6338 if (!PyUnicode_Check(arg)) {
6339 PyErr_SetString(PyExc_TypeError,
6340 "configuration names must be strings or integers");
Guido van Rossumbce56a62007-05-10 18:04:33 +00006341 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006342 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006343 confname = _PyUnicode_AsString(arg);
6344 if (confname == NULL)
6345 return 0;
6346 while (lo < hi) {
6347 mid = (lo + hi) / 2;
6348 cmp = strcmp(confname, table[mid].name);
6349 if (cmp < 0)
6350 hi = mid;
6351 else if (cmp > 0)
6352 lo = mid + 1;
6353 else {
6354 *valuep = table[mid].value;
6355 return 1;
6356 }
6357 }
6358 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6359 return 0;
6360 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006361}
6362
6363
6364#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6365static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006366#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006368#endif
6369#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006370 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006371#endif
Fred Drakec9680921999-12-13 16:37:25 +00006372#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006373 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006374#endif
6375#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006376 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006377#endif
6378#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006379 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006380#endif
6381#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006382 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006383#endif
6384#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006385 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006386#endif
6387#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006388 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006389#endif
6390#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006391 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006392#endif
6393#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006394 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006395#endif
6396#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006397 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006398#endif
6399#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006400 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006401#endif
6402#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006403 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006404#endif
6405#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006406 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006407#endif
6408#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006409 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006410#endif
6411#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006412 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006413#endif
6414#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006415 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006416#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00006417#ifdef _PC_ACL_ENABLED
6418 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
6419#endif
6420#ifdef _PC_MIN_HOLE_SIZE
6421 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
6422#endif
6423#ifdef _PC_ALLOC_SIZE_MIN
6424 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
6425#endif
6426#ifdef _PC_REC_INCR_XFER_SIZE
6427 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
6428#endif
6429#ifdef _PC_REC_MAX_XFER_SIZE
6430 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
6431#endif
6432#ifdef _PC_REC_MIN_XFER_SIZE
6433 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
6434#endif
6435#ifdef _PC_REC_XFER_ALIGN
6436 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
6437#endif
6438#ifdef _PC_SYMLINK_MAX
6439 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
6440#endif
6441#ifdef _PC_XATTR_ENABLED
6442 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
6443#endif
6444#ifdef _PC_XATTR_EXISTS
6445 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
6446#endif
6447#ifdef _PC_TIMESTAMP_RESOLUTION
6448 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
6449#endif
Fred Drakec9680921999-12-13 16:37:25 +00006450};
6451
Fred Drakec9680921999-12-13 16:37:25 +00006452static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006453conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006454{
6455 return conv_confname(arg, valuep, posix_constants_pathconf,
6456 sizeof(posix_constants_pathconf)
6457 / sizeof(struct constdef));
6458}
6459#endif
6460
6461#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006462PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006463"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006464Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006465If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006466
6467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006468posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006469{
6470 PyObject *result = NULL;
6471 int name, fd;
6472
Fred Drake12c6e2d1999-12-14 21:25:03 +00006473 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6474 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006475 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006476
Victor Stinner8c62be82010-05-06 00:08:46 +00006477 errno = 0;
6478 limit = fpathconf(fd, name);
6479 if (limit == -1 && errno != 0)
6480 posix_error();
6481 else
6482 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006483 }
6484 return result;
6485}
6486#endif
6487
6488
6489#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006490PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006491"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006492Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006493If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006494
6495static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006496posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006497{
6498 PyObject *result = NULL;
6499 int name;
6500 char *path;
6501
6502 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6503 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006504 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006505
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 errno = 0;
6507 limit = pathconf(path, name);
6508 if (limit == -1 && errno != 0) {
6509 if (errno == EINVAL)
6510 /* could be a path or name problem */
6511 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006512 else
Victor Stinner8c62be82010-05-06 00:08:46 +00006513 posix_error_with_filename(path);
6514 }
6515 else
6516 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006517 }
6518 return result;
6519}
6520#endif
6521
6522#ifdef HAVE_CONFSTR
6523static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006524#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006525 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006526#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006527#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006528 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006529#endif
6530#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006531 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006532#endif
Fred Draked86ed291999-12-15 15:34:33 +00006533#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006534 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006535#endif
6536#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006537 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006538#endif
6539#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006540 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006541#endif
6542#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006543 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006544#endif
Fred Drakec9680921999-12-13 16:37:25 +00006545#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006546 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006547#endif
6548#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006549 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006550#endif
6551#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006552 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006553#endif
6554#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006555 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006556#endif
6557#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006558 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006559#endif
6560#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006561 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006562#endif
6563#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006564 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006565#endif
6566#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006567 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006568#endif
Fred Draked86ed291999-12-15 15:34:33 +00006569#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006570 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006571#endif
Fred Drakec9680921999-12-13 16:37:25 +00006572#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006573 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006574#endif
Fred Draked86ed291999-12-15 15:34:33 +00006575#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006576 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006577#endif
6578#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006579 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006580#endif
6581#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006582 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006583#endif
6584#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006586#endif
Fred Drakec9680921999-12-13 16:37:25 +00006587#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006588 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006589#endif
6590#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006591 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006592#endif
6593#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006594 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006595#endif
6596#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006597 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006598#endif
6599#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006600 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006601#endif
6602#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006603 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006604#endif
6605#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006606 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006607#endif
6608#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006609 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006610#endif
6611#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006612 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006613#endif
6614#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006615 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006616#endif
6617#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006618 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006619#endif
6620#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006621 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006622#endif
6623#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006624 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006625#endif
6626#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006627 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006628#endif
6629#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006630 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006631#endif
6632#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006633 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006634#endif
Fred Draked86ed291999-12-15 15:34:33 +00006635#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006636 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006637#endif
6638#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006639 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006640#endif
6641#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006642 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006643#endif
6644#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006645 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006646#endif
6647#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006648 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006649#endif
6650#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006651 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006652#endif
6653#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006654 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006655#endif
6656#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006657 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006658#endif
6659#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006660 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006661#endif
6662#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006663 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006664#endif
6665#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006666 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006667#endif
6668#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006669 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006670#endif
6671#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006672 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006673#endif
Fred Drakec9680921999-12-13 16:37:25 +00006674};
6675
6676static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006677conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006678{
6679 return conv_confname(arg, valuep, posix_constants_confstr,
6680 sizeof(posix_constants_confstr)
6681 / sizeof(struct constdef));
6682}
6683
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006684PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006685"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006686Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006687
6688static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006689posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006690{
6691 PyObject *result = NULL;
6692 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00006693 char buffer[255];
Victor Stinner8c62be82010-05-06 00:08:46 +00006694 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006695
Victor Stinnercb043522010-09-10 23:49:04 +00006696 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
6697 return NULL;
6698
6699 errno = 0;
6700 len = confstr(name, buffer, sizeof(buffer));
6701 if (len == 0) {
6702 if (errno) {
6703 posix_error();
6704 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00006705 }
6706 else {
Victor Stinnercb043522010-09-10 23:49:04 +00006707 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00006708 }
6709 }
Victor Stinnercb043522010-09-10 23:49:04 +00006710
6711 if ((unsigned int)len >= sizeof(buffer)) {
6712 char *buf = PyMem_Malloc(len);
6713 if (buf == NULL)
6714 return PyErr_NoMemory();
6715 confstr(name, buf, len);
6716 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
6717 PyMem_Free(buf);
6718 }
6719 else
6720 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006721 return result;
6722}
6723#endif
6724
6725
6726#ifdef HAVE_SYSCONF
6727static struct constdef posix_constants_sysconf[] = {
6728#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00006729 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006730#endif
6731#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00006732 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006733#endif
6734#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006735 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006736#endif
6737#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006738 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006739#endif
6740#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006741 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006742#endif
6743#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00006744 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006745#endif
6746#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00006747 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006748#endif
6749#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006750 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006751#endif
6752#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00006753 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006754#endif
6755#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006756 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006757#endif
Fred Draked86ed291999-12-15 15:34:33 +00006758#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006759 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006760#endif
6761#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006763#endif
Fred Drakec9680921999-12-13 16:37:25 +00006764#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006765 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006766#endif
Fred Drakec9680921999-12-13 16:37:25 +00006767#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006768 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006769#endif
6770#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006771 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006772#endif
6773#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006774 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006775#endif
6776#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006778#endif
6779#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006780 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006781#endif
Fred Draked86ed291999-12-15 15:34:33 +00006782#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006783 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006784#endif
Fred Drakec9680921999-12-13 16:37:25 +00006785#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006786 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006787#endif
6788#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006790#endif
6791#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006792 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006793#endif
6794#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006795 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006796#endif
6797#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006798 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006799#endif
Fred Draked86ed291999-12-15 15:34:33 +00006800#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006802#endif
Fred Drakec9680921999-12-13 16:37:25 +00006803#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006805#endif
6806#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006807 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006808#endif
6809#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006810 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006811#endif
6812#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006813 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006814#endif
6815#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006816 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006817#endif
6818#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006820#endif
6821#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006822 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006823#endif
6824#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006825 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006826#endif
6827#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006828 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006829#endif
6830#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006831 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006832#endif
6833#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006834 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006835#endif
6836#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006837 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006838#endif
6839#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006840 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006841#endif
6842#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006843 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006844#endif
6845#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006846 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006847#endif
6848#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006849 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006850#endif
6851#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006852 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006853#endif
6854#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006855 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006856#endif
6857#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006858 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006859#endif
6860#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006861 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006862#endif
6863#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006864 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006865#endif
6866#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006867 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006868#endif
6869#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006871#endif
Fred Draked86ed291999-12-15 15:34:33 +00006872#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00006873 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006874#endif
Fred Drakec9680921999-12-13 16:37:25 +00006875#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006876 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006877#endif
6878#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006879 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006880#endif
6881#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006882 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006883#endif
Fred Draked86ed291999-12-15 15:34:33 +00006884#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006885 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006886#endif
Fred Drakec9680921999-12-13 16:37:25 +00006887#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00006888 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006889#endif
Fred Draked86ed291999-12-15 15:34:33 +00006890#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00006891 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006892#endif
6893#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00006894 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006895#endif
Fred Drakec9680921999-12-13 16:37:25 +00006896#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006897 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006898#endif
6899#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006900 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006901#endif
6902#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006903 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006904#endif
6905#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006906 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006907#endif
Fred Draked86ed291999-12-15 15:34:33 +00006908#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00006909 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006910#endif
Fred Drakec9680921999-12-13 16:37:25 +00006911#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00006912 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006913#endif
6914#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00006915 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006916#endif
6917#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006918 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006919#endif
6920#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006921 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006922#endif
6923#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00006924 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006925#endif
6926#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00006927 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006928#endif
6929#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00006930 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006931#endif
Fred Draked86ed291999-12-15 15:34:33 +00006932#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00006933 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006934#endif
Fred Drakec9680921999-12-13 16:37:25 +00006935#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006936 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006937#endif
6938#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006939 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006940#endif
Fred Draked86ed291999-12-15 15:34:33 +00006941#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006942 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006943#endif
Fred Drakec9680921999-12-13 16:37:25 +00006944#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006945 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006946#endif
6947#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006948 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006949#endif
6950#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006951 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006952#endif
6953#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006954 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006955#endif
6956#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006957 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006958#endif
6959#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006960 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006961#endif
6962#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006963 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006964#endif
6965#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006966 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00006967#endif
6968#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00006969 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00006970#endif
Fred Draked86ed291999-12-15 15:34:33 +00006971#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006972 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00006973#endif
6974#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00006975 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00006976#endif
Fred Drakec9680921999-12-13 16:37:25 +00006977#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00006978 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00006979#endif
6980#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006981 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006982#endif
6983#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006984 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006985#endif
6986#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006987 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006988#endif
6989#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006990 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006991#endif
6992#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006993 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006994#endif
6995#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00006996 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00006997#endif
6998#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00006999 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00007000#endif
7001#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007002 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00007003#endif
7004#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007005 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00007006#endif
7007#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00007008 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00007009#endif
7010#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007011 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00007012#endif
7013#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007014 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00007015#endif
7016#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00007017 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00007018#endif
7019#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00007020 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00007021#endif
7022#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00007023 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00007024#endif
7025#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00007026 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00007027#endif
7028#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007029 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007030#endif
7031#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007032 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007033#endif
7034#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00007035 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00007036#endif
7037#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007038 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007039#endif
7040#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007041 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007042#endif
7043#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00007044 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00007045#endif
7046#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007047 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007048#endif
7049#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007050 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007051#endif
7052#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007053 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00007054#endif
7055#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00007056 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00007057#endif
7058#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007059 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007060#endif
7061#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007062 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007063#endif
7064#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007065 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00007066#endif
7067#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007068 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007069#endif
7070#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007071 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007072#endif
7073#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007074 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007075#endif
7076#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007077 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007078#endif
7079#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007080 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007081#endif
Fred Draked86ed291999-12-15 15:34:33 +00007082#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00007083 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00007084#endif
Fred Drakec9680921999-12-13 16:37:25 +00007085#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00007086 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00007087#endif
7088#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007089 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007090#endif
7091#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00007092 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00007093#endif
7094#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007095 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007096#endif
7097#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007098 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007099#endif
7100#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007101 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007102#endif
7103#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00007104 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00007105#endif
7106#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007107 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007108#endif
7109#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007110 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007111#endif
7112#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007113 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007114#endif
7115#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007116 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007117#endif
7118#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007119 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00007120#endif
7121#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007122 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00007123#endif
7124#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00007125 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00007126#endif
7127#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007128 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007129#endif
7130#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007131 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007132#endif
7133#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007134 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007135#endif
7136#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007137 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00007138#endif
7139#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007140 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007141#endif
7142#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007143 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007144#endif
7145#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007146 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007147#endif
7148#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007149 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007150#endif
7151#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007152 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007153#endif
7154#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007155 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007156#endif
7157#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007158 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007159#endif
7160#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007161 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007162#endif
7163#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007164 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007165#endif
7166#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007167 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007168#endif
7169#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007170 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007171#endif
7172#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007173 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007174#endif
7175#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007176 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007177#endif
7178#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007179 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007180#endif
7181#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007182 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007183#endif
7184#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007185 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007186#endif
7187#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007188 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007189#endif
7190#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007191 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007192#endif
7193#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007194 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007195#endif
7196#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007197 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007198#endif
7199#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007200 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007201#endif
7202#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007203 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007204#endif
7205#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007206 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007207#endif
7208#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007209 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007210#endif
7211#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007212 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007213#endif
7214#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007215 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007216#endif
7217#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007218 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007219#endif
7220};
7221
7222static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007223conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007224{
7225 return conv_confname(arg, valuep, posix_constants_sysconf,
7226 sizeof(posix_constants_sysconf)
7227 / sizeof(struct constdef));
7228}
7229
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007230PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007231"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007232Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007233
7234static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007235posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007236{
7237 PyObject *result = NULL;
7238 int name;
7239
7240 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7241 int value;
7242
7243 errno = 0;
7244 value = sysconf(name);
7245 if (value == -1 && errno != 0)
7246 posix_error();
7247 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007248 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007249 }
7250 return result;
7251}
7252#endif
7253
7254
Fred Drakebec628d1999-12-15 18:31:10 +00007255/* This code is used to ensure that the tables of configuration value names
7256 * are in sorted order as required by conv_confname(), and also to build the
7257 * the exported dictionaries that are used to publish information about the
7258 * names available on the host platform.
7259 *
7260 * Sorting the table at runtime ensures that the table is properly ordered
7261 * when used, even for platforms we're not able to test on. It also makes
7262 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007263 */
Fred Drakebec628d1999-12-15 18:31:10 +00007264
7265static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007266cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007267{
7268 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007269 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007270 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007271 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007272
7273 return strcmp(c1->name, c2->name);
7274}
7275
7276static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007277setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007278 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007279{
Fred Drakebec628d1999-12-15 18:31:10 +00007280 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007281 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007282
7283 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7284 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007285 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007286 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007287
Barry Warsaw3155db32000-04-13 15:20:40 +00007288 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007289 PyObject *o = PyLong_FromLong(table[i].value);
7290 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7291 Py_XDECREF(o);
7292 Py_DECREF(d);
7293 return -1;
7294 }
7295 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007296 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007297 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007298}
7299
Fred Drakebec628d1999-12-15 18:31:10 +00007300/* Return -1 on failure, 0 on success. */
7301static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007302setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007303{
7304#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007305 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007306 sizeof(posix_constants_pathconf)
7307 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007308 "pathconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007309 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007310#endif
7311#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007312 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007313 sizeof(posix_constants_confstr)
7314 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007315 "confstr_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007316 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007317#endif
7318#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007319 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007320 sizeof(posix_constants_sysconf)
7321 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007322 "sysconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007323 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007324#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007325 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007326}
Fred Draked86ed291999-12-15 15:34:33 +00007327
7328
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007329PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007330"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007331Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007332in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007333
7334static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007335posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007336{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007337 abort();
7338 /*NOTREACHED*/
7339 Py_FatalError("abort() called from Python code didn't abort!");
7340 return NULL;
7341}
Fred Drakebec628d1999-12-15 18:31:10 +00007342
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007343#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007344PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007345"startfile(filepath [, operation]) - Start a file with its associated\n\
7346application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007347\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007348When \"operation\" is not specified or \"open\", this acts like\n\
7349double-clicking the file in Explorer, or giving the file name as an\n\
7350argument to the DOS \"start\" command: the file is opened with whatever\n\
7351application (if any) its extension is associated.\n\
7352When another \"operation\" is given, it specifies what should be done with\n\
7353the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007354\n\
7355startfile returns as soon as the associated application is launched.\n\
7356There is no option to wait for the application to close, and no way\n\
7357to retrieve the application's exit status.\n\
7358\n\
7359The filepath is relative to the current directory. If you want to use\n\
7360an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007361the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007362
7363static PyObject *
7364win32_startfile(PyObject *self, PyObject *args)
7365{
Victor Stinner8c62be82010-05-06 00:08:46 +00007366 PyObject *ofilepath;
7367 char *filepath;
7368 char *operation = NULL;
7369 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007370
Victor Stinner8c62be82010-05-06 00:08:46 +00007371 PyObject *unipath, *woperation = NULL;
7372 if (!PyArg_ParseTuple(args, "U|s:startfile",
7373 &unipath, &operation)) {
7374 PyErr_Clear();
7375 goto normal;
7376 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007377
Victor Stinner8c62be82010-05-06 00:08:46 +00007378 if (operation) {
7379 woperation = PyUnicode_DecodeASCII(operation,
7380 strlen(operation), NULL);
7381 if (!woperation) {
7382 PyErr_Clear();
7383 operation = NULL;
7384 goto normal;
7385 }
7386 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007387
Victor Stinner8c62be82010-05-06 00:08:46 +00007388 Py_BEGIN_ALLOW_THREADS
7389 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7390 PyUnicode_AS_UNICODE(unipath),
7391 NULL, NULL, SW_SHOWNORMAL);
7392 Py_END_ALLOW_THREADS
7393
7394 Py_XDECREF(woperation);
7395 if (rc <= (HINSTANCE)32) {
7396 PyObject *errval = win32_error_unicode("startfile",
7397 PyUnicode_AS_UNICODE(unipath));
7398 return errval;
7399 }
7400 Py_INCREF(Py_None);
7401 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007402
7403normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007404 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7405 PyUnicode_FSConverter, &ofilepath,
7406 &operation))
7407 return NULL;
7408 filepath = PyBytes_AsString(ofilepath);
7409 Py_BEGIN_ALLOW_THREADS
7410 rc = ShellExecute((HWND)0, operation, filepath,
7411 NULL, NULL, SW_SHOWNORMAL);
7412 Py_END_ALLOW_THREADS
7413 if (rc <= (HINSTANCE)32) {
7414 PyObject *errval = win32_error("startfile", filepath);
7415 Py_DECREF(ofilepath);
7416 return errval;
7417 }
7418 Py_DECREF(ofilepath);
7419 Py_INCREF(Py_None);
7420 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007421}
7422#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007423
Martin v. Löwis438b5342002-12-27 10:16:42 +00007424#ifdef HAVE_GETLOADAVG
7425PyDoc_STRVAR(posix_getloadavg__doc__,
7426"getloadavg() -> (float, float, float)\n\n\
7427Return the number of processes in the system run queue averaged over\n\
7428the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7429was unobtainable");
7430
7431static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007432posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007433{
7434 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007435 if (getloadavg(loadavg, 3)!=3) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007436 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7437 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007438 } else
Victor Stinner8c62be82010-05-06 00:08:46 +00007439 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007440}
7441#endif
7442
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007443#ifdef MS_WINDOWS
7444
7445PyDoc_STRVAR(win32_urandom__doc__,
7446"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007447Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007448
7449typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7450 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7451 DWORD dwFlags );
7452typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7453 BYTE *pbBuffer );
7454
7455static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007456/* This handle is never explicitly released. Instead, the operating
7457 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007458static HCRYPTPROV hCryptProv = 0;
7459
Tim Peters4ad82172004-08-30 17:02:04 +00007460static PyObject*
7461win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007462{
Victor Stinner8c62be82010-05-06 00:08:46 +00007463 int howMany;
7464 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007465
Victor Stinner8c62be82010-05-06 00:08:46 +00007466 /* Read arguments */
7467 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7468 return NULL;
7469 if (howMany < 0)
7470 return PyErr_Format(PyExc_ValueError,
7471 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007472
Victor Stinner8c62be82010-05-06 00:08:46 +00007473 if (hCryptProv == 0) {
7474 HINSTANCE hAdvAPI32 = NULL;
7475 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007476
Victor Stinner8c62be82010-05-06 00:08:46 +00007477 /* Obtain handle to the DLL containing CryptoAPI
7478 This should not fail */
7479 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7480 if(hAdvAPI32 == NULL)
7481 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007482
Victor Stinner8c62be82010-05-06 00:08:46 +00007483 /* Obtain pointers to the CryptoAPI functions
7484 This will fail on some early versions of Win95 */
7485 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7486 hAdvAPI32,
7487 "CryptAcquireContextA");
7488 if (pCryptAcquireContext == NULL)
7489 return PyErr_Format(PyExc_NotImplementedError,
7490 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007491
Victor Stinner8c62be82010-05-06 00:08:46 +00007492 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7493 hAdvAPI32, "CryptGenRandom");
7494 if (pCryptGenRandom == NULL)
7495 return PyErr_Format(PyExc_NotImplementedError,
7496 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007497
Victor Stinner8c62be82010-05-06 00:08:46 +00007498 /* Acquire context */
7499 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7500 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7501 return win32_error("CryptAcquireContext", NULL);
7502 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007503
Victor Stinner8c62be82010-05-06 00:08:46 +00007504 /* Allocate bytes */
7505 result = PyBytes_FromStringAndSize(NULL, howMany);
7506 if (result != NULL) {
7507 /* Get random data */
7508 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7509 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7510 PyBytes_AS_STRING(result))) {
7511 Py_DECREF(result);
7512 return win32_error("CryptGenRandom", NULL);
7513 }
7514 }
7515 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007516}
7517#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007518
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007519PyDoc_STRVAR(device_encoding__doc__,
7520"device_encoding(fd) -> str\n\n\
7521Return a string describing the encoding of the device\n\
7522if the output is a terminal; else return None.");
7523
7524static PyObject *
7525device_encoding(PyObject *self, PyObject *args)
7526{
Victor Stinner8c62be82010-05-06 00:08:46 +00007527 int fd;
7528 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7529 return NULL;
7530 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7531 Py_INCREF(Py_None);
7532 return Py_None;
7533 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007534#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007535 if (fd == 0) {
7536 char buf[100];
7537 sprintf(buf, "cp%d", GetConsoleCP());
7538 return PyUnicode_FromString(buf);
7539 }
7540 if (fd == 1 || fd == 2) {
7541 char buf[100];
7542 sprintf(buf, "cp%d", GetConsoleOutputCP());
7543 return PyUnicode_FromString(buf);
7544 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007545#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007546 {
7547 char *codeset = nl_langinfo(CODESET);
7548 if (codeset != NULL && codeset[0] != 0)
7549 return PyUnicode_FromString(codeset);
7550 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007551#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007552 Py_INCREF(Py_None);
7553 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007554}
7555
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007556#ifdef __VMS
7557/* Use openssl random routine */
7558#include <openssl/rand.h>
7559PyDoc_STRVAR(vms_urandom__doc__,
7560"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007561Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007562
7563static PyObject*
7564vms_urandom(PyObject *self, PyObject *args)
7565{
Victor Stinner8c62be82010-05-06 00:08:46 +00007566 int howMany;
7567 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007568
Victor Stinner8c62be82010-05-06 00:08:46 +00007569 /* Read arguments */
7570 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7571 return NULL;
7572 if (howMany < 0)
7573 return PyErr_Format(PyExc_ValueError,
7574 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007575
Victor Stinner8c62be82010-05-06 00:08:46 +00007576 /* Allocate bytes */
7577 result = PyBytes_FromStringAndSize(NULL, howMany);
7578 if (result != NULL) {
7579 /* Get random data */
7580 if (RAND_pseudo_bytes((unsigned char*)
7581 PyBytes_AS_STRING(result),
7582 howMany) < 0) {
7583 Py_DECREF(result);
7584 return PyErr_Format(PyExc_ValueError,
7585 "RAND_pseudo_bytes");
7586 }
7587 }
7588 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007589}
7590#endif
7591
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007592#ifdef HAVE_SETRESUID
7593PyDoc_STRVAR(posix_setresuid__doc__,
7594"setresuid(ruid, euid, suid)\n\n\
7595Set the current process's real, effective, and saved user ids.");
7596
7597static PyObject*
7598posix_setresuid (PyObject *self, PyObject *args)
7599{
Victor Stinner8c62be82010-05-06 00:08:46 +00007600 /* We assume uid_t is no larger than a long. */
7601 long ruid, euid, suid;
7602 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7603 return NULL;
7604 if (setresuid(ruid, euid, suid) < 0)
7605 return posix_error();
7606 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007607}
7608#endif
7609
7610#ifdef HAVE_SETRESGID
7611PyDoc_STRVAR(posix_setresgid__doc__,
7612"setresgid(rgid, egid, sgid)\n\n\
7613Set the current process's real, effective, and saved group ids.");
7614
7615static PyObject*
7616posix_setresgid (PyObject *self, PyObject *args)
7617{
Victor Stinner8c62be82010-05-06 00:08:46 +00007618 /* We assume uid_t is no larger than a long. */
7619 long rgid, egid, sgid;
7620 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7621 return NULL;
7622 if (setresgid(rgid, egid, sgid) < 0)
7623 return posix_error();
7624 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007625}
7626#endif
7627
7628#ifdef HAVE_GETRESUID
7629PyDoc_STRVAR(posix_getresuid__doc__,
7630"getresuid() -> (ruid, euid, suid)\n\n\
7631Get tuple of the current process's real, effective, and saved user ids.");
7632
7633static PyObject*
7634posix_getresuid (PyObject *self, PyObject *noargs)
7635{
Victor Stinner8c62be82010-05-06 00:08:46 +00007636 uid_t ruid, euid, suid;
7637 long l_ruid, l_euid, l_suid;
7638 if (getresuid(&ruid, &euid, &suid) < 0)
7639 return posix_error();
7640 /* Force the values into long's as we don't know the size of uid_t. */
7641 l_ruid = ruid;
7642 l_euid = euid;
7643 l_suid = suid;
7644 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007645}
7646#endif
7647
7648#ifdef HAVE_GETRESGID
7649PyDoc_STRVAR(posix_getresgid__doc__,
7650"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00007651Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007652
7653static PyObject*
7654posix_getresgid (PyObject *self, PyObject *noargs)
7655{
Victor Stinner8c62be82010-05-06 00:08:46 +00007656 uid_t rgid, egid, sgid;
7657 long l_rgid, l_egid, l_sgid;
7658 if (getresgid(&rgid, &egid, &sgid) < 0)
7659 return posix_error();
7660 /* Force the values into long's as we don't know the size of uid_t. */
7661 l_rgid = rgid;
7662 l_egid = egid;
7663 l_sgid = sgid;
7664 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007665}
7666#endif
7667
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007668static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007669 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007670#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007671 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007672#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007673 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007674#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007675 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007676#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007677 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007678#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007679 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007680#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007681#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007682 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007683#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007684#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007685 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007686#endif /* HAVE_LCHMOD */
7687#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007688 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007689#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007690#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007691 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007692#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007693#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007694 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007695#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007696#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007697 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007698#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007699#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007700 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007701#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007702#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00007703 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7704 METH_NOARGS, posix_getcwd__doc__},
7705 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7706 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007707#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007708#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007709 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007710#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7712 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7713 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007714#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00007715 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007716#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007717#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007718 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007719#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007720#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007721 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007722#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007723 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7724 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7725 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00007726 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007727#ifdef HAVE_SYMLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007729#endif /* HAVE_SYMLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007730#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin74e45612010-07-09 15:58:59 +00007731 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
7732 win_symlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007733#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007734#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00007735 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007736#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007737 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007738#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007739 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007740#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00007741 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7742 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7743 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007744#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00007745 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007746#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00007747 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007748#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00007749 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7750 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007751#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007752#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00007753 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7754 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007755#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00007756 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7757 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007758#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007759#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007760#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00007761 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007762#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007763#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00007764 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007765#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007766#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00007767 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007768#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007769#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007771#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007772#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007773 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007774#endif /* HAVE_GETEGID */
7775#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007776 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007777#endif /* HAVE_GETEUID */
7778#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007779 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007780#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007781#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007782 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007783#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007785#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007786 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007787#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007788#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007789 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007790#endif /* HAVE_GETPPID */
7791#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007792 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007793#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007794#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007795 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007796#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007797#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00007798 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007799#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007800#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007802#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007803#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007805#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007806#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007807 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7808 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007809#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007810#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007811 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007812#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007813#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007814 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007815#endif /* HAVE_SETEUID */
7816#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007817 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007818#endif /* HAVE_SETEGID */
7819#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007820 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007821#endif /* HAVE_SETREUID */
7822#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007823 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007824#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007825#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007826 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007827#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007828#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007829 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007830#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00007831#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007832 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00007833#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007834#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007835 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007836#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007837#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007838 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007839#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007840#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007841 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007842#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007843#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00007844 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007845#endif /* HAVE_WAIT3 */
7846#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00007847 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007848#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007849#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007850 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007851#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007852#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007853 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007854#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007855#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007856 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007857#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007858#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007860#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007861#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007863#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007864#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007865 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007866#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00007867 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7868 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7869 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7870 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7871 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7872 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7873 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7874 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7875 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7876 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7877 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007878#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00007879 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007880#endif
7881#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00007882 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007883#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007884#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00007885 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007886#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007887#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00007888 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7889 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7890 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007891#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007892#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00007893 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007894#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007895#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007896 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007897#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007898#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007899 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007900#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007901 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007902#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00007903 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007904#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007905#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007906 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007907#endif
7908#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007909 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007910#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007911#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007912#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00007913 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007914#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007915#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00007916 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007917#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007918#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00007919 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007920#endif /* WIFSTOPPED */
7921#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00007922 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007923#endif /* WIFSIGNALED */
7924#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00007925 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007926#endif /* WIFEXITED */
7927#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00007928 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007929#endif /* WEXITSTATUS */
7930#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007931 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007932#endif /* WTERMSIG */
7933#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007935#endif /* WSTOPSIG */
7936#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007937#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007938 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007939#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007940#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007941 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007942#endif
Fred Drakec9680921999-12-13 16:37:25 +00007943#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00007944 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007945#endif
7946#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007947 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007948#endif
7949#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007950 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007951#endif
7952#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007953 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007954#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007955 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007956#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007957 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00007958 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +00007959 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00007960#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007961#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00007962 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007963#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007964 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007965 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007966 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007967 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007968 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007969 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007970#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007971 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007972#endif
7973#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007974 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007975#endif
7976#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007977 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007978#endif
7979#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007980 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007981#endif
7982
Victor Stinner8c62be82010-05-06 00:08:46 +00007983 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007984};
7985
7986
Barry Warsaw4a342091996-12-19 23:50:02 +00007987static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007988ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007989{
Victor Stinner8c62be82010-05-06 00:08:46 +00007990 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007991}
7992
Guido van Rossumd48f2521997-12-05 22:19:34 +00007993#if defined(PYOS_OS2)
7994/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007995static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007996{
7997 APIRET rc;
7998 ULONG values[QSV_MAX+1];
7999 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008000 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008001
8002 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008003 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008004 Py_END_ALLOW_THREADS
8005
8006 if (rc != NO_ERROR) {
8007 os2_error(rc);
8008 return -1;
8009 }
8010
Fred Drake4d1e64b2002-04-15 19:40:07 +00008011 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8012 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8013 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8014 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8015 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8016 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8017 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008018
8019 switch (values[QSV_VERSION_MINOR]) {
8020 case 0: ver = "2.00"; break;
8021 case 10: ver = "2.10"; break;
8022 case 11: ver = "2.11"; break;
8023 case 30: ver = "3.00"; break;
8024 case 40: ver = "4.00"; break;
8025 case 50: ver = "5.00"; break;
8026 default:
Tim Peters885d4572001-11-28 20:27:42 +00008027 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00008028 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00008029 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008030 ver = &tmp[0];
8031 }
8032
8033 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008034 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008035 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008036
8037 /* Add Indicator of Which Drive was Used to Boot the System */
8038 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8039 tmp[1] = ':';
8040 tmp[2] = '\0';
8041
Fred Drake4d1e64b2002-04-15 19:40:07 +00008042 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008043}
8044#endif
8045
Barry Warsaw4a342091996-12-19 23:50:02 +00008046static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008047all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008048{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008049#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008050 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008051#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008052#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008053 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008054#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008055#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008056 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008057#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008058#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008059 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008060#endif
Fred Drakec9680921999-12-13 16:37:25 +00008061#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008062 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00008063#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008064#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008065 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008066#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008067#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008068 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008069#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008070#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00008071 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008072#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008073#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00008074 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008075#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008076#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008077 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008078#endif
8079#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008080 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008081#endif
8082#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00008083 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008084#endif
8085#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00008086 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008087#endif
8088#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008089 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008090#endif
8091#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00008092 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008093#endif
8094#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008095 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008096#endif
8097#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008098 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008099#endif
8100#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008101 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008102#endif
8103#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008104 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008105#endif
8106#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008107 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008108#endif
8109#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00008110 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008111#endif
8112#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008113 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008114#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008115#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008116 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008117#endif
8118#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00008119 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008120#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008121#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008122 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008123#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008124#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008125 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008126#endif
8127#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008128 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008129#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008130
Tim Peters5aa91602002-01-30 05:46:57 +00008131/* MS Windows */
8132#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008133 /* Don't inherit in child processes. */
8134 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008135#endif
8136#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00008137 /* Optimize for short life (keep in memory). */
8138 /* MS forgot to define this one with a non-underscore form too. */
8139 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008140#endif
8141#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008142 /* Automatically delete when last handle is closed. */
8143 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008144#endif
8145#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008146 /* Optimize for random access. */
8147 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008148#endif
8149#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008150 /* Optimize for sequential access. */
8151 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008152#endif
8153
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008154/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008155#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008156 /* Send a SIGIO signal whenever input or output
8157 becomes available on file descriptor */
8158 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008159#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008160#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008161 /* Direct disk access. */
8162 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008163#endif
8164#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008165 /* Must be a directory. */
8166 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008167#endif
8168#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008169 /* Do not follow links. */
8170 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008171#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008172#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008173 /* Do not update the access time. */
8174 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008175#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008176
Victor Stinner8c62be82010-05-06 00:08:46 +00008177 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008178#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008179 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008180#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008181#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008182 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008183#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008184#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008185 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008186#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008187#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008188 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008189#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008190#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008191 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008192#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008193#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008194 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008195#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008196#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008197 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008198#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008199#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008200 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008201#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008202#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008203 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008204#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008205#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008206 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008207#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008208#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008209 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008210#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008211#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008212 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008213#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008214#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008215 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008216#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008217#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008218 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008219#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008220#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008221 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008222#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008223#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008224 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008225#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008226#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008227 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008228#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008229
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008230 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008231#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008232 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008233#endif /* ST_RDONLY */
8234#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008235 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008236#endif /* ST_NOSUID */
8237
Guido van Rossum246bc171999-02-01 23:54:31 +00008238#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008239#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008240 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8241 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8242 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8243 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8244 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8245 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8246 if (ins(d, "P_PM", (long)P_PM)) return -1;
8247 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8248 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8249 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8250 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8251 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8252 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8253 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8254 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8255 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8256 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8257 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8258 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8259 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008260#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008261 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8262 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8263 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8264 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8265 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008266#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008267#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008268
Guido van Rossumd48f2521997-12-05 22:19:34 +00008269#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008270 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008271#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008272 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008273}
8274
8275
Tim Peters5aa91602002-01-30 05:46:57 +00008276#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008277#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008278#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008279
8280#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008281#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008282#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008283
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008284#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008285#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008286#define MODNAME "posix"
8287#endif
8288
Martin v. Löwis1a214512008-06-11 05:26:20 +00008289static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008290 PyModuleDef_HEAD_INIT,
8291 MODNAME,
8292 posix__doc__,
8293 -1,
8294 posix_methods,
8295 NULL,
8296 NULL,
8297 NULL,
8298 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008299};
8300
8301
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008302PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008303INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008304{
Victor Stinner8c62be82010-05-06 00:08:46 +00008305 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008306
Victor Stinner8c62be82010-05-06 00:08:46 +00008307 m = PyModule_Create(&posixmodule);
8308 if (m == NULL)
8309 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008310
Victor Stinner8c62be82010-05-06 00:08:46 +00008311 /* Initialize environ dictionary */
8312 v = convertenviron();
8313 Py_XINCREF(v);
8314 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8315 return NULL;
8316 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008317
Victor Stinner8c62be82010-05-06 00:08:46 +00008318 if (all_ins(m))
8319 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008320
Victor Stinner8c62be82010-05-06 00:08:46 +00008321 if (setup_confname_tables(m))
8322 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008323
Victor Stinner8c62be82010-05-06 00:08:46 +00008324 Py_INCREF(PyExc_OSError);
8325 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008326
Guido van Rossumb3d39562000-01-31 18:41:26 +00008327#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008328 if (posix_putenv_garbage == NULL)
8329 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008330#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008331
Victor Stinner8c62be82010-05-06 00:08:46 +00008332 if (!initialized) {
8333 stat_result_desc.name = MODNAME ".stat_result";
8334 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8335 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8336 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8337 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8338 structseq_new = StatResultType.tp_new;
8339 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008340
Victor Stinner8c62be82010-05-06 00:08:46 +00008341 statvfs_result_desc.name = MODNAME ".statvfs_result";
8342 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008343#ifdef NEED_TICKS_PER_SECOND
8344# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008345 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008346# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008347 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008348# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008349 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008350# endif
8351#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008352 }
8353 Py_INCREF((PyObject*) &StatResultType);
8354 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8355 Py_INCREF((PyObject*) &StatVFSResultType);
8356 PyModule_AddObject(m, "statvfs_result",
8357 (PyObject*) &StatVFSResultType);
8358 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008359
8360#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008361 /*
8362 * Step 2 of weak-linking support on Mac OS X.
8363 *
8364 * The code below removes functions that are not available on the
8365 * currently active platform.
8366 *
8367 * This block allow one to use a python binary that was build on
8368 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8369 * OSX 10.4.
8370 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008371#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008372 if (fstatvfs == NULL) {
8373 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8374 return NULL;
8375 }
8376 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008377#endif /* HAVE_FSTATVFS */
8378
8379#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008380 if (statvfs == NULL) {
8381 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8382 return NULL;
8383 }
8384 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008385#endif /* HAVE_STATVFS */
8386
8387# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008388 if (lchown == NULL) {
8389 if (PyObject_DelAttrString(m, "lchown") == -1) {
8390 return NULL;
8391 }
8392 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008393#endif /* HAVE_LCHOWN */
8394
8395
8396#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008397 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008398
Guido van Rossumb6775db1994-08-01 11:34:53 +00008399}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008400
8401#ifdef __cplusplus
8402}
8403#endif