blob: 07ede0adb0cd8d86e08aafae7f8acad1f563ae93 [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
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000440/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000441#ifdef WITH_NEXT_FRAMEWORK
442/* On Darwin/MacOSX a shared library or framework has no access to
443** environ directly, we must obtain it with _NSGetEnviron().
444*/
445#include <crt_externs.h>
446static char **environ;
447#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000448extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000449#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000450
Barry Warsaw53699e91996-12-10 23:23:01 +0000451static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000452convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453{
Victor Stinner8c62be82010-05-06 00:08:46 +0000454 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000455#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000456 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000457#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000458 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000459#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000460#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000461 APIRET rc;
462 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
463#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000464
Victor Stinner8c62be82010-05-06 00:08:46 +0000465 d = PyDict_New();
466 if (d == NULL)
467 return NULL;
468#ifdef WITH_NEXT_FRAMEWORK
469 if (environ == NULL)
470 environ = *_NSGetEnviron();
471#endif
472#ifdef MS_WINDOWS
473 /* _wenviron must be initialized in this way if the program is started
474 through main() instead of wmain(). */
475 _wgetenv(L"");
476 if (_wenviron == NULL)
477 return d;
478 /* This part ignores errors */
479 for (e = _wenviron; *e != NULL; e++) {
480 PyObject *k;
481 PyObject *v;
482 wchar_t *p = wcschr(*e, L'=');
483 if (p == NULL)
484 continue;
485 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
486 if (k == NULL) {
487 PyErr_Clear();
488 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000489 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000490 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
491 if (v == NULL) {
492 PyErr_Clear();
493 Py_DECREF(k);
494 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000495 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000496 if (PyDict_GetItem(d, k) == NULL) {
497 if (PyDict_SetItem(d, k, v) != 0)
498 PyErr_Clear();
499 }
500 Py_DECREF(k);
501 Py_DECREF(v);
502 }
503#else
504 if (environ == NULL)
505 return d;
506 /* This part ignores errors */
507 for (e = environ; *e != NULL; e++) {
508 PyObject *k;
509 PyObject *v;
510 char *p = strchr(*e, '=');
511 if (p == NULL)
512 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000513 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000514 if (k == NULL) {
515 PyErr_Clear();
516 continue;
517 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000518 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000519 if (v == NULL) {
520 PyErr_Clear();
521 Py_DECREF(k);
522 continue;
523 }
524 if (PyDict_GetItem(d, k) == NULL) {
525 if (PyDict_SetItem(d, k, v) != 0)
526 PyErr_Clear();
527 }
528 Py_DECREF(k);
529 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000530 }
531#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000532#if defined(PYOS_OS2)
533 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
534 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
535 PyObject *v = PyBytes_FromString(buffer);
536 PyDict_SetItemString(d, "BEGINLIBPATH", v);
537 Py_DECREF(v);
538 }
539 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
540 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
541 PyObject *v = PyBytes_FromString(buffer);
542 PyDict_SetItemString(d, "ENDLIBPATH", v);
543 Py_DECREF(v);
544 }
545#endif
546 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000547}
548
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000549/* Set a POSIX-specific error from errno, and return NULL */
550
Barry Warsawd58d7641998-07-23 16:14:40 +0000551static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000552posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000553{
Victor Stinner8c62be82010-05-06 00:08:46 +0000554 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000555}
Barry Warsawd58d7641998-07-23 16:14:40 +0000556static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000557posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000558{
Victor Stinner8c62be82010-05-06 00:08:46 +0000559 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000560}
561
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000562
Mark Hammondef8b6542001-05-13 08:04:26 +0000563static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000564posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000565{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000566 PyObject *name_str, *rc;
567 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
568 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000569 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000570 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
571 name_str);
572 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000573 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000574}
575
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000576#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000577static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000578win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000579{
Victor Stinner8c62be82010-05-06 00:08:46 +0000580 /* XXX We should pass the function name along in the future.
581 (winreg.c also wants to pass the function name.)
582 This would however require an additional param to the
583 Windows error object, which is non-trivial.
584 */
585 errno = GetLastError();
586 if (filename)
587 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
588 else
589 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000590}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000591
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000592static PyObject *
593win32_error_unicode(char* function, Py_UNICODE* filename)
594{
Victor Stinner8c62be82010-05-06 00:08:46 +0000595 /* XXX - see win32_error for comments on 'function' */
596 errno = GetLastError();
597 if (filename)
598 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
599 else
600 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000601}
602
Thomas Wouters477c8d52006-05-27 19:21:47 +0000603static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000604convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000605{
Victor Stinner8c62be82010-05-06 00:08:46 +0000606 if (PyUnicode_CheckExact(*param))
607 Py_INCREF(*param);
608 else if (PyUnicode_Check(*param))
609 /* For a Unicode subtype that's not a Unicode object,
610 return a true Unicode object with the same data. */
611 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
612 PyUnicode_GET_SIZE(*param));
613 else
614 *param = PyUnicode_FromEncodedObject(*param,
615 Py_FileSystemDefaultEncoding,
616 "strict");
617 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000618}
619
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000620#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000621
Guido van Rossumd48f2521997-12-05 22:19:34 +0000622#if defined(PYOS_OS2)
623/**********************************************************************
624 * Helper Function to Trim and Format OS/2 Messages
625 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000626static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000627os2_formatmsg(char *msgbuf, int msglen, char *reason)
628{
629 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
630
631 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
632 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
633
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000634 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000635 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
636 }
637
638 /* Add Optional Reason Text */
639 if (reason) {
640 strcat(msgbuf, " : ");
641 strcat(msgbuf, reason);
642 }
643}
644
645/**********************************************************************
646 * Decode an OS/2 Operating System Error Code
647 *
648 * A convenience function to lookup an OS/2 error code and return a
649 * text message we can use to raise a Python exception.
650 *
651 * Notes:
652 * The messages for errors returned from the OS/2 kernel reside in
653 * the file OSO001.MSG in the \OS2 directory hierarchy.
654 *
655 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000656static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000657os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
658{
659 APIRET rc;
660 ULONG msglen;
661
662 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
663 Py_BEGIN_ALLOW_THREADS
664 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
665 errorcode, "oso001.msg", &msglen);
666 Py_END_ALLOW_THREADS
667
668 if (rc == NO_ERROR)
669 os2_formatmsg(msgbuf, msglen, reason);
670 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000671 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000672 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000673
674 return msgbuf;
675}
676
677/* Set an OS/2-specific error and return NULL. OS/2 kernel
678 errors are not in a global variable e.g. 'errno' nor are
679 they congruent with posix error numbers. */
680
Victor Stinner8c62be82010-05-06 00:08:46 +0000681static PyObject *
682os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000683{
684 char text[1024];
685 PyObject *v;
686
687 os2_strerror(text, sizeof(text), code, "");
688
689 v = Py_BuildValue("(is)", code, text);
690 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000691 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000692 Py_DECREF(v);
693 }
694 return NULL; /* Signal to Python that an Exception is Pending */
695}
696
697#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000698
699/* POSIX generic methods */
700
Barry Warsaw53699e91996-12-10 23:23:01 +0000701static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000702posix_fildes(PyObject *fdobj, int (*func)(int))
703{
Victor Stinner8c62be82010-05-06 00:08:46 +0000704 int fd;
705 int res;
706 fd = PyObject_AsFileDescriptor(fdobj);
707 if (fd < 0)
708 return NULL;
709 if (!_PyVerify_fd(fd))
710 return posix_error();
711 Py_BEGIN_ALLOW_THREADS
712 res = (*func)(fd);
713 Py_END_ALLOW_THREADS
714 if (res < 0)
715 return posix_error();
716 Py_INCREF(Py_None);
717 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000718}
Guido van Rossum21142a01999-01-08 21:05:37 +0000719
720static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000721posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000722{
Victor Stinner8c62be82010-05-06 00:08:46 +0000723 PyObject *opath1 = NULL;
724 char *path1;
725 int res;
726 if (!PyArg_ParseTuple(args, format,
727 PyUnicode_FSConverter, &opath1))
728 return NULL;
729 path1 = PyBytes_AsString(opath1);
730 Py_BEGIN_ALLOW_THREADS
731 res = (*func)(path1);
732 Py_END_ALLOW_THREADS
733 if (res < 0)
734 return posix_error_with_allocated_filename(opath1);
735 Py_DECREF(opath1);
736 Py_INCREF(Py_None);
737 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000738}
739
Barry Warsaw53699e91996-12-10 23:23:01 +0000740static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000741posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000742 char *format,
743 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000744{
Victor Stinner8c62be82010-05-06 00:08:46 +0000745 PyObject *opath1 = NULL, *opath2 = NULL;
746 char *path1, *path2;
747 int res;
748 if (!PyArg_ParseTuple(args, format,
749 PyUnicode_FSConverter, &opath1,
750 PyUnicode_FSConverter, &opath2)) {
751 return NULL;
752 }
753 path1 = PyBytes_AsString(opath1);
754 path2 = PyBytes_AsString(opath2);
755 Py_BEGIN_ALLOW_THREADS
756 res = (*func)(path1, path2);
757 Py_END_ALLOW_THREADS
758 Py_DECREF(opath1);
759 Py_DECREF(opath2);
760 if (res != 0)
761 /* XXX how to report both path1 and path2??? */
762 return posix_error();
763 Py_INCREF(Py_None);
764 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000765}
766
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000767#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000768static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000769win32_1str(PyObject* args, char* func,
770 char* format, BOOL (__stdcall *funcA)(LPCSTR),
771 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000772{
Victor Stinner8c62be82010-05-06 00:08:46 +0000773 PyObject *uni;
774 char *ansi;
775 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000776
Victor Stinner8c62be82010-05-06 00:08:46 +0000777 if (!PyArg_ParseTuple(args, wformat, &uni))
778 PyErr_Clear();
779 else {
780 Py_BEGIN_ALLOW_THREADS
781 result = funcW(PyUnicode_AsUnicode(uni));
782 Py_END_ALLOW_THREADS
783 if (!result)
784 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
785 Py_INCREF(Py_None);
786 return Py_None;
787 }
788 if (!PyArg_ParseTuple(args, format, &ansi))
789 return NULL;
790 Py_BEGIN_ALLOW_THREADS
791 result = funcA(ansi);
792 Py_END_ALLOW_THREADS
793 if (!result)
794 return win32_error(func, ansi);
795 Py_INCREF(Py_None);
796 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000797
798}
799
800/* This is a reimplementation of the C library's chdir function,
801 but one that produces Win32 errors instead of DOS error codes.
802 chdir is essentially a wrapper around SetCurrentDirectory; however,
803 it also needs to set "magic" environment variables indicating
804 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000805static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000806win32_chdir(LPCSTR path)
807{
Victor Stinner8c62be82010-05-06 00:08:46 +0000808 char new_path[MAX_PATH+1];
809 int result;
810 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000811
Victor Stinner8c62be82010-05-06 00:08:46 +0000812 if(!SetCurrentDirectoryA(path))
813 return FALSE;
814 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
815 if (!result)
816 return FALSE;
817 /* In the ANSI API, there should not be any paths longer
818 than MAX_PATH. */
819 assert(result <= MAX_PATH+1);
820 if (strncmp(new_path, "\\\\", 2) == 0 ||
821 strncmp(new_path, "//", 2) == 0)
822 /* UNC path, nothing to do. */
823 return TRUE;
824 env[1] = new_path[0];
825 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000826}
827
828/* The Unicode version differs from the ANSI version
829 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000830static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000831win32_wchdir(LPCWSTR path)
832{
Victor Stinner8c62be82010-05-06 00:08:46 +0000833 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
834 int result;
835 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000836
Victor Stinner8c62be82010-05-06 00:08:46 +0000837 if(!SetCurrentDirectoryW(path))
838 return FALSE;
839 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
840 if (!result)
841 return FALSE;
842 if (result > MAX_PATH+1) {
843 new_path = malloc(result * sizeof(wchar_t));
844 if (!new_path) {
845 SetLastError(ERROR_OUTOFMEMORY);
846 return FALSE;
847 }
848 result = GetCurrentDirectoryW(result, new_path);
849 if (!result) {
850 free(new_path);
851 return FALSE;
852 }
853 }
854 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
855 wcsncmp(new_path, L"//", 2) == 0)
856 /* UNC path, nothing to do. */
857 return TRUE;
858 env[1] = new_path[0];
859 result = SetEnvironmentVariableW(env, new_path);
860 if (new_path != _new_path)
861 free(new_path);
862 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000863}
864#endif
865
Martin v. Löwis14694662006-02-03 12:54:16 +0000866#ifdef MS_WINDOWS
867/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
868 - time stamps are restricted to second resolution
869 - file modification times suffer from forth-and-back conversions between
870 UTC and local time
871 Therefore, we implement our own stat, based on the Win32 API directly.
872*/
Victor Stinner8c62be82010-05-06 00:08:46 +0000873#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000874
875struct win32_stat{
876 int st_dev;
877 __int64 st_ino;
878 unsigned short st_mode;
879 int st_nlink;
880 int st_uid;
881 int st_gid;
882 int st_rdev;
883 __int64 st_size;
884 int st_atime;
885 int st_atime_nsec;
886 int st_mtime;
887 int st_mtime_nsec;
888 int st_ctime;
889 int st_ctime_nsec;
890};
891
892static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
893
894static void
895FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
896{
Victor Stinner8c62be82010-05-06 00:08:46 +0000897 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
898 /* Cannot simply cast and dereference in_ptr,
899 since it might not be aligned properly */
900 __int64 in;
901 memcpy(&in, in_ptr, sizeof(in));
902 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
903 /* XXX Win32 supports time stamps past 2038; we currently don't */
904 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
Martin v. Löwis14694662006-02-03 12:54:16 +0000905}
906
Thomas Wouters477c8d52006-05-27 19:21:47 +0000907static void
908time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
909{
Victor Stinner8c62be82010-05-06 00:08:46 +0000910 /* XXX endianness */
911 __int64 out;
912 out = time_in + secs_between_epochs;
913 out = out * 10000000 + nsec_in / 100;
914 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000915}
916
Martin v. Löwis14694662006-02-03 12:54:16 +0000917/* Below, we *know* that ugo+r is 0444 */
918#if _S_IREAD != 0400
919#error Unsupported C library
920#endif
921static int
922attributes_to_mode(DWORD attr)
923{
Victor Stinner8c62be82010-05-06 00:08:46 +0000924 int m = 0;
925 if (attr & FILE_ATTRIBUTE_DIRECTORY)
926 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
927 else
928 m |= _S_IFREG;
929 if (attr & FILE_ATTRIBUTE_READONLY)
930 m |= 0444;
931 else
932 m |= 0666;
933 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +0000934}
935
936static int
937attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
938{
Victor Stinner8c62be82010-05-06 00:08:46 +0000939 memset(result, 0, sizeof(*result));
940 result->st_mode = attributes_to_mode(info->dwFileAttributes);
941 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
942 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
943 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
944 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +0000945
Victor Stinner8c62be82010-05-06 00:08:46 +0000946 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +0000947}
948
Guido van Rossumd8faa362007-04-27 19:54:29 +0000949static BOOL
950attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
951{
Victor Stinner8c62be82010-05-06 00:08:46 +0000952 HANDLE hFindFile;
953 WIN32_FIND_DATAA FileData;
954 hFindFile = FindFirstFileA(pszFile, &FileData);
955 if (hFindFile == INVALID_HANDLE_VALUE)
956 return FALSE;
957 FindClose(hFindFile);
958 pfad->dwFileAttributes = FileData.dwFileAttributes;
959 pfad->ftCreationTime = FileData.ftCreationTime;
960 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
961 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
962 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
963 pfad->nFileSizeLow = FileData.nFileSizeLow;
964 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000965}
966
967static BOOL
968attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
969{
Victor Stinner8c62be82010-05-06 00:08:46 +0000970 HANDLE hFindFile;
971 WIN32_FIND_DATAW FileData;
972 hFindFile = FindFirstFileW(pszFile, &FileData);
973 if (hFindFile == INVALID_HANDLE_VALUE)
974 return FALSE;
975 FindClose(hFindFile);
976 pfad->dwFileAttributes = FileData.dwFileAttributes;
977 pfad->ftCreationTime = FileData.ftCreationTime;
978 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
979 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
980 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
981 pfad->nFileSizeLow = FileData.nFileSizeLow;
982 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000983}
984
Brian Curtind40e6f72010-07-08 21:39:08 +0000985/* About the following functions: win32_lstat, win32_lstat_w, win32_stat,
986 win32_stat_w
987
988 In Posix, stat automatically traverses symlinks and returns the stat
989 structure for the target. In Windows, the equivalent GetFileAttributes by
990 default does not traverse symlinks and instead returns attributes for
991 the symlink.
992
993 Therefore, win32_lstat will get the attributes traditionally, and
994 win32_stat will first explicitly resolve the symlink target and then will
995 call win32_lstat on that result.
996
997 The _w represent Unicode equivalents of the aformentioned ANSI functions. */
998
999static int
1000win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001001{
Victor Stinner8c62be82010-05-06 00:08:46 +00001002 WIN32_FILE_ATTRIBUTE_DATA info;
1003 int code;
1004 char *dot;
Brian Curtind40e6f72010-07-08 21:39:08 +00001005 WIN32_FIND_DATAA find_data;
1006 HANDLE find_data_handle;
Victor Stinner8c62be82010-05-06 00:08:46 +00001007 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1008 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1009 /* Protocol violation: we explicitly clear errno, instead of
1010 setting it to a POSIX error. Callers should use GetLastError. */
1011 errno = 0;
1012 return -1;
1013 } else {
1014 /* Could not get attributes on open file. Fall back to
1015 reading the directory. */
1016 if (!attributes_from_dir(path, &info)) {
1017 /* Very strange. This should not fail now */
1018 errno = 0;
1019 return -1;
1020 }
1021 }
1022 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001023
Victor Stinner8c62be82010-05-06 00:08:46 +00001024 code = attribute_data_to_stat(&info, result);
1025 if (code != 0)
1026 return code;
Brian Curtind40e6f72010-07-08 21:39:08 +00001027
1028 /* Get WIN32_FIND_DATA structure for the path to determine if
1029 it is a symlink */
1030 if(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1031 find_data_handle = FindFirstFileA(path, &find_data);
1032 if(find_data_handle != INVALID_HANDLE_VALUE) {
1033 if(find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
1034 /* first clear the S_IFMT bits */
1035 result->st_mode ^= (result->st_mode & 0170000);
1036 /* now set the bits that make this a symlink */
1037 result->st_mode |= 0120000;
1038 }
1039 FindClose(find_data_handle);
1040 }
1041 }
1042
Victor Stinner8c62be82010-05-06 00:08:46 +00001043 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1044 dot = strrchr(path, '.');
1045 if (dot) {
Brian Curtind40e6f72010-07-08 21:39:08 +00001046 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1047 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00001048 result->st_mode |= 0111;
1049 }
1050 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001051}
1052
Victor Stinner8c62be82010-05-06 00:08:46 +00001053static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001054win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001055{
Victor Stinner8c62be82010-05-06 00:08:46 +00001056 int code;
1057 const wchar_t *dot;
1058 WIN32_FILE_ATTRIBUTE_DATA info;
Brian Curtind40e6f72010-07-08 21:39:08 +00001059 WIN32_FIND_DATAW find_data;
1060 HANDLE find_data_handle;
Victor Stinner8c62be82010-05-06 00:08:46 +00001061 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1062 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1063 /* Protocol violation: we explicitly clear errno, instead of
1064 setting it to a POSIX error. Callers should use GetLastError. */
1065 errno = 0;
1066 return -1;
1067 } else {
Brian Curtind40e6f72010-07-08 21:39:08 +00001068 /* Could not get attributes on open file. Fall back to reading
1069 the directory. */
1070 if (!attributes_from_dir_w(path, &info)) {
1071 /* Very strange. This should not fail now */
1072 errno = 0;
1073 return -1;
1074 }
1075 }
1076 }
1077 code = attribute_data_to_stat(&info, result);
1078 if (code < 0)
1079 return code;
1080
1081 /* Get WIN32_FIND_DATA structure for the path to determine if
1082 it is a symlink */
1083 if(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1084 find_data_handle = FindFirstFileW(path, &find_data);
1085 if(find_data_handle != INVALID_HANDLE_VALUE) {
1086 if(find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
1087 /* first clear the S_IFMT bits */
1088 result->st_mode ^= (result->st_mode & 0170000);
1089 /* now set the bits that make this a symlink */
1090 result->st_mode |= 0120000;
1091 }
1092 FindClose(find_data_handle);
1093 }
1094 }
1095
1096 /* Set IFEXEC if it is an .exe, .bat, ... */
1097 dot = wcsrchr(path, '.');
1098 if (dot) {
1099 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1100 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1101 result->st_mode |= 0111;
1102 }
1103 return code;
1104}
1105
1106/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1107static int has_GetFinalPathNameByHandle = 0;
1108static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1109 DWORD);
1110static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1111 DWORD);
1112static int
1113check_GetFinalPathNameByHandle()
1114{
1115 HINSTANCE hKernel32;
1116 /* only recheck */
1117 if (!has_GetFinalPathNameByHandle)
1118 {
1119 hKernel32 = GetModuleHandle("KERNEL32");
1120 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1121 "GetFinalPathNameByHandleA");
1122 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1123 "GetFinalPathNameByHandleW");
Brian Curtin74e45612010-07-09 15:58:59 +00001124 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1125 Py_GetFinalPathNameByHandleW;
Brian Curtind40e6f72010-07-08 21:39:08 +00001126 }
1127 return has_GetFinalPathNameByHandle;
1128}
1129
1130static int
1131win32_stat(const char* path, struct win32_stat *result)
1132{
1133 /* Traverse the symlink to the target using
1134 GetFinalPathNameByHandle()
1135 */
1136 int code;
1137 HANDLE hFile;
1138 int buf_size;
1139 char *target_path;
1140 int result_length;
1141 WIN32_FILE_ATTRIBUTE_DATA info;
1142
1143 if(!check_GetFinalPathNameByHandle()) {
1144 /* if the OS doesn't have GetFinalPathNameByHandle, it doesn't
1145 have symlinks, so just fall back to the traditional behavior
1146 found in lstat. */
1147 return win32_lstat(path, result);
1148 }
1149
1150 hFile = CreateFileA(
1151 path,
1152 0, /* desired access */
1153 0, /* share mode */
1154 NULL, /* security attributes */
1155 OPEN_EXISTING,
1156 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Antoine Pitrou38425292010-09-21 18:19:07 +00001157 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
Brian Curtind40e6f72010-07-08 21:39:08 +00001158 NULL);
1159
1160 if(hFile == INVALID_HANDLE_VALUE) {
1161 /* Either the target doesn't exist, or we don't have access to
1162 get a handle to it. If the former, we need to return an error.
1163 If the latter, we can use attributes_from_dir. */
1164 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1165 /* Protocol violation: we explicitly clear errno, instead of
1166 setting it to a POSIX error. Callers should use GetLastError. */
1167 errno = 0;
1168 return -1;
1169 } else {
1170 /* Could not get attributes on open file. Fall back to
1171 reading the directory. */
1172 if (!attributes_from_dir(path, &info)) {
1173 /* Very strange. This should not fail now */
1174 errno = 0;
1175 return -1;
1176 }
1177 }
1178 code = attribute_data_to_stat(&info, result);
1179 }
Antoine Pitrou38425292010-09-21 18:19:07 +00001180 else {
1181 /* We have a good handle to the target, use it to determine the target
1182 path name (then we'll call lstat on it). */
1183 buf_size = Py_GetFinalPathNameByHandleA(hFile, 0, 0, VOLUME_NAME_DOS);
1184 if(!buf_size) return -1;
1185 /* Due to a slight discrepancy between GetFinalPathNameByHandleA
1186 and GetFinalPathNameByHandleW, we must allocate one more byte
1187 than reported. */
1188 target_path = (char *)malloc((buf_size+2)*sizeof(char));
1189 result_length = Py_GetFinalPathNameByHandleA(hFile, target_path,
1190 buf_size+1, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00001191
Antoine Pitrou38425292010-09-21 18:19:07 +00001192 if(!result_length) {
1193 free(target_path);
1194 return -1;
1195 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001196
Antoine Pitrou38425292010-09-21 18:19:07 +00001197 if(!CloseHandle(hFile)) {
1198 free(target_path);
1199 return -1;
1200 }
1201
1202 target_path[result_length] = 0;
1203 code = win32_lstat(target_path, result);
1204 free(target_path);
1205 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001206
1207 return code;
1208}
1209
1210static int
1211win32_stat_w(const wchar_t* path, struct win32_stat *result)
1212{
1213 /* Traverse the symlink to the target using GetFinalPathNameByHandle() */
1214 int code;
1215 HANDLE hFile;
1216 int buf_size;
1217 wchar_t *target_path;
1218 int result_length;
1219 WIN32_FILE_ATTRIBUTE_DATA info;
1220
1221 if(!check_GetFinalPathNameByHandle()) {
1222 /* If the OS doesn't have GetFinalPathNameByHandle, it doesn't have
1223 symlinks, so just fall back to the traditional behavior found
1224 in lstat. */
1225 return win32_lstat_w(path, result);
1226 }
1227
1228 hFile = CreateFileW(
1229 path,
1230 0, /* desired access */
1231 0, /* share mode */
1232 NULL, /* security attributes */
1233 OPEN_EXISTING,
1234 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1235 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1236 NULL);
Antoine Pitroub73caab2010-08-09 23:39:31 +00001237
Brian Curtind40e6f72010-07-08 21:39:08 +00001238 if(hFile == INVALID_HANDLE_VALUE) {
1239 /* Either the target doesn't exist, or we don't have access to
1240 get a handle to it. If the former, we need to return an error.
1241 If the latter, we can use attributes_from_dir. */
1242 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1243 /* Protocol violation: we explicitly clear errno, instead of
1244 setting it to a POSIX error. Callers should use GetLastError. */
1245 errno = 0;
1246 return -1;
1247 } else {
Victor Stinner8c62be82010-05-06 00:08:46 +00001248 /* Could not get attributes on open file. Fall back to
1249 reading the directory. */
1250 if (!attributes_from_dir_w(path, &info)) {
1251 /* Very strange. This should not fail now */
1252 errno = 0;
1253 return -1;
1254 }
1255 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001256 code = attribute_data_to_stat(&info, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001257 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001258 else {
1259 /* We have a good handle to the target, use it to determine the target
1260 path name (then we'll call lstat on it). */
1261 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_DOS);
1262 if(!buf_size)
1263 return -1;
1264
1265 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
1266 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
1267 buf_size, VOLUME_NAME_DOS);
1268
Antoine Pitrou38425292010-09-21 18:19:07 +00001269 if(!result_length) {
1270 free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00001271 return -1;
Antoine Pitrou38425292010-09-21 18:19:07 +00001272 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001273
Antoine Pitrou38425292010-09-21 18:19:07 +00001274 if(!CloseHandle(hFile)) {
1275 free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00001276 return -1;
Antoine Pitrou38425292010-09-21 18:19:07 +00001277 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001278
1279 target_path[result_length] = 0;
1280 code = win32_lstat_w(target_path, result);
1281 free(target_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001282 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001283
Victor Stinner8c62be82010-05-06 00:08:46 +00001284 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001285}
1286
1287static int
1288win32_fstat(int file_number, struct win32_stat *result)
1289{
Victor Stinner8c62be82010-05-06 00:08:46 +00001290 BY_HANDLE_FILE_INFORMATION info;
1291 HANDLE h;
1292 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001293
Victor Stinner8c62be82010-05-06 00:08:46 +00001294 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001295
Victor Stinner8c62be82010-05-06 00:08:46 +00001296 /* Protocol violation: we explicitly clear errno, instead of
1297 setting it to a POSIX error. Callers should use GetLastError. */
1298 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001299
Victor Stinner8c62be82010-05-06 00:08:46 +00001300 if (h == INVALID_HANDLE_VALUE) {
1301 /* This is really a C library error (invalid file handle).
1302 We set the Win32 error to the closes one matching. */
1303 SetLastError(ERROR_INVALID_HANDLE);
1304 return -1;
1305 }
1306 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001307
Victor Stinner8c62be82010-05-06 00:08:46 +00001308 type = GetFileType(h);
1309 if (type == FILE_TYPE_UNKNOWN) {
1310 DWORD error = GetLastError();
1311 if (error != 0) {
1312 return -1;
1313 }
1314 /* else: valid but unknown file */
1315 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001316
Victor Stinner8c62be82010-05-06 00:08:46 +00001317 if (type != FILE_TYPE_DISK) {
1318 if (type == FILE_TYPE_CHAR)
1319 result->st_mode = _S_IFCHR;
1320 else if (type == FILE_TYPE_PIPE)
1321 result->st_mode = _S_IFIFO;
1322 return 0;
1323 }
1324
1325 if (!GetFileInformationByHandle(h, &info)) {
1326 return -1;
1327 }
1328
1329 /* similar to stat() */
1330 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1331 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
Brian Curtin74e45612010-07-09 15:58:59 +00001332 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime,
1333 &result->st_ctime_nsec);
1334 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime,
1335 &result->st_mtime_nsec);
1336 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime,
1337 &result->st_atime_nsec);
Victor Stinner8c62be82010-05-06 00:08:46 +00001338 /* specific to fstat() */
1339 result->st_nlink = info.nNumberOfLinks;
1340 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1341 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001342}
1343
1344#endif /* MS_WINDOWS */
1345
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001346PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001347"stat_result: Result from stat or lstat.\n\n\
1348This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001349 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001350or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1351\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001352Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1353or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001354\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001355See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001356
1357static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001358 {"st_mode", "protection bits"},
1359 {"st_ino", "inode"},
1360 {"st_dev", "device"},
1361 {"st_nlink", "number of hard links"},
1362 {"st_uid", "user ID of owner"},
1363 {"st_gid", "group ID of owner"},
1364 {"st_size", "total size, in bytes"},
1365 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1366 {NULL, "integer time of last access"},
1367 {NULL, "integer time of last modification"},
1368 {NULL, "integer time of last change"},
1369 {"st_atime", "time of last access"},
1370 {"st_mtime", "time of last modification"},
1371 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001372#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001373 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001374#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001375#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001376 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001377#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001378#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001379 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001380#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001381#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001382 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001383#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001384#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001385 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001386#endif
1387#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001388 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001389#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001390 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001391};
1392
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001393#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001394#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001395#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001396#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001397#endif
1398
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001399#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001400#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1401#else
1402#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1403#endif
1404
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001405#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001406#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1407#else
1408#define ST_RDEV_IDX ST_BLOCKS_IDX
1409#endif
1410
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001411#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1412#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1413#else
1414#define ST_FLAGS_IDX ST_RDEV_IDX
1415#endif
1416
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001417#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001418#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001419#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001420#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001421#endif
1422
1423#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1424#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1425#else
1426#define ST_BIRTHTIME_IDX ST_GEN_IDX
1427#endif
1428
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001429static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001430 "stat_result", /* name */
1431 stat_result__doc__, /* doc */
1432 stat_result_fields,
1433 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001434};
1435
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001436PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001437"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1438This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001439 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001440or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001441\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001442See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001443
1444static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001445 {"f_bsize", },
1446 {"f_frsize", },
1447 {"f_blocks", },
1448 {"f_bfree", },
1449 {"f_bavail", },
1450 {"f_files", },
1451 {"f_ffree", },
1452 {"f_favail", },
1453 {"f_flag", },
1454 {"f_namemax",},
1455 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001456};
1457
1458static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001459 "statvfs_result", /* name */
1460 statvfs_result__doc__, /* doc */
1461 statvfs_result_fields,
1462 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001463};
1464
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001465static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001466static PyTypeObject StatResultType;
1467static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001468static newfunc structseq_new;
1469
1470static PyObject *
1471statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1472{
Victor Stinner8c62be82010-05-06 00:08:46 +00001473 PyStructSequence *result;
1474 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001475
Victor Stinner8c62be82010-05-06 00:08:46 +00001476 result = (PyStructSequence*)structseq_new(type, args, kwds);
1477 if (!result)
1478 return NULL;
1479 /* If we have been initialized from a tuple,
1480 st_?time might be set to None. Initialize it
1481 from the int slots. */
1482 for (i = 7; i <= 9; i++) {
1483 if (result->ob_item[i+3] == Py_None) {
1484 Py_DECREF(Py_None);
1485 Py_INCREF(result->ob_item[i]);
1486 result->ob_item[i+3] = result->ob_item[i];
1487 }
1488 }
1489 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001490}
1491
1492
1493
1494/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001495static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001496
1497PyDoc_STRVAR(stat_float_times__doc__,
1498"stat_float_times([newval]) -> oldval\n\n\
1499Determine whether os.[lf]stat represents time stamps as float objects.\n\
1500If newval is True, future calls to stat() return floats, if it is False,\n\
1501future calls return ints. \n\
1502If newval is omitted, return the current setting.\n");
1503
1504static PyObject*
1505stat_float_times(PyObject* self, PyObject *args)
1506{
Victor Stinner8c62be82010-05-06 00:08:46 +00001507 int newval = -1;
1508 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1509 return NULL;
1510 if (newval == -1)
1511 /* Return old value */
1512 return PyBool_FromLong(_stat_float_times);
1513 _stat_float_times = newval;
1514 Py_INCREF(Py_None);
1515 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001516}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001517
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001518static void
1519fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1520{
Victor Stinner8c62be82010-05-06 00:08:46 +00001521 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001522#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001523 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001524#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001525 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001526#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001527 if (!ival)
1528 return;
1529 if (_stat_float_times) {
1530 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1531 } else {
1532 fval = ival;
1533 Py_INCREF(fval);
1534 }
1535 PyStructSequence_SET_ITEM(v, index, ival);
1536 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001537}
1538
Tim Peters5aa91602002-01-30 05:46:57 +00001539/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001540 (used by posix_stat() and posix_fstat()) */
1541static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001542_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001543{
Victor Stinner8c62be82010-05-06 00:08:46 +00001544 unsigned long ansec, mnsec, cnsec;
1545 PyObject *v = PyStructSequence_New(&StatResultType);
1546 if (v == NULL)
1547 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001548
Victor Stinner8c62be82010-05-06 00:08:46 +00001549 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001550#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001551 PyStructSequence_SET_ITEM(v, 1,
1552 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001553#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001554 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001555#endif
1556#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001557 PyStructSequence_SET_ITEM(v, 2,
1558 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001559#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001560 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001561#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001562 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1563 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1564 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001565#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001566 PyStructSequence_SET_ITEM(v, 6,
1567 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001568#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001569 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001570#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001571
Martin v. Löwis14694662006-02-03 12:54:16 +00001572#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001573 ansec = st->st_atim.tv_nsec;
1574 mnsec = st->st_mtim.tv_nsec;
1575 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001576#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001577 ansec = st->st_atimespec.tv_nsec;
1578 mnsec = st->st_mtimespec.tv_nsec;
1579 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001580#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001581 ansec = st->st_atime_nsec;
1582 mnsec = st->st_mtime_nsec;
1583 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001584#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001585 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001586#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001587 fill_time(v, 7, st->st_atime, ansec);
1588 fill_time(v, 8, st->st_mtime, mnsec);
1589 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001590
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001591#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001592 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1593 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001594#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001595#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001596 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1597 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001598#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001599#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001600 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1601 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001602#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001603#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001604 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1605 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001606#endif
1607#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001608 {
1609 PyObject *val;
1610 unsigned long bsec,bnsec;
1611 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001612#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001613 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001614#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001615 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001616#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001617 if (_stat_float_times) {
1618 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1619 } else {
1620 val = PyLong_FromLong((long)bsec);
1621 }
1622 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1623 val);
1624 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001625#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001626#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001627 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1628 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001629#endif
Fred Drake699f3522000-06-29 21:12:41 +00001630
Victor Stinner8c62be82010-05-06 00:08:46 +00001631 if (PyErr_Occurred()) {
1632 Py_DECREF(v);
1633 return NULL;
1634 }
Fred Drake699f3522000-06-29 21:12:41 +00001635
Victor Stinner8c62be82010-05-06 00:08:46 +00001636 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001637}
1638
Barry Warsaw53699e91996-12-10 23:23:01 +00001639static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001640posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001641 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001642#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001643 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001644#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001645 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001646#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001647 char *wformat,
1648 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001649{
Victor Stinner8c62be82010-05-06 00:08:46 +00001650 STRUCT_STAT st;
1651 PyObject *opath;
1652 char *path;
1653 int res;
1654 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001655
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001656#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001657 PyUnicodeObject *po;
1658 if (PyArg_ParseTuple(args, wformat, &po)) {
1659 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001660
Victor Stinner8c62be82010-05-06 00:08:46 +00001661 Py_BEGIN_ALLOW_THREADS
1662 /* PyUnicode_AS_UNICODE result OK without
1663 thread lock as it is a simple dereference. */
1664 res = wstatfunc(wpath, &st);
1665 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001666
Victor Stinner8c62be82010-05-06 00:08:46 +00001667 if (res != 0)
1668 return win32_error_unicode("stat", wpath);
1669 return _pystat_fromstructstat(&st);
1670 }
1671 /* Drop the argument parsing error as narrow strings
1672 are also valid. */
1673 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001674#endif
1675
Victor Stinner8c62be82010-05-06 00:08:46 +00001676 if (!PyArg_ParseTuple(args, format,
1677 PyUnicode_FSConverter, &opath))
1678 return NULL;
1679 path = PyBytes_AsString(opath);
1680 Py_BEGIN_ALLOW_THREADS
1681 res = (*statfunc)(path, &st);
1682 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001683
Victor Stinner8c62be82010-05-06 00:08:46 +00001684 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001685#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001686 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001687#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001688 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001689#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001690 }
1691 else
1692 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001693
Victor Stinner8c62be82010-05-06 00:08:46 +00001694 Py_DECREF(opath);
1695 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001696}
1697
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001698/* POSIX methods */
1699
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001700PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001701"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001702Use the real uid/gid to test for access to a path. Note that most\n\
1703operations will use the effective uid/gid, therefore this routine can\n\
1704be used in a suid/sgid environment to test if the invoking user has the\n\
1705specified access to the path. The mode argument can be F_OK to test\n\
1706existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001707
1708static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001709posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001710{
Victor Stinner8c62be82010-05-06 00:08:46 +00001711 PyObject *opath;
1712 char *path;
1713 int mode;
1714
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001715#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001716 DWORD attr;
1717 PyUnicodeObject *po;
1718 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1719 Py_BEGIN_ALLOW_THREADS
1720 /* PyUnicode_AS_UNICODE OK without thread lock as
1721 it is a simple dereference. */
1722 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1723 Py_END_ALLOW_THREADS
1724 goto finish;
1725 }
1726 /* Drop the argument parsing error as narrow strings
1727 are also valid. */
1728 PyErr_Clear();
1729 if (!PyArg_ParseTuple(args, "O&i:access",
1730 PyUnicode_FSConverter, &opath, &mode))
1731 return NULL;
1732 path = PyBytes_AsString(opath);
1733 Py_BEGIN_ALLOW_THREADS
1734 attr = GetFileAttributesA(path);
1735 Py_END_ALLOW_THREADS
1736 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001737finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001738 if (attr == 0xFFFFFFFF)
1739 /* File does not exist, or cannot read attributes */
1740 return PyBool_FromLong(0);
1741 /* Access is possible if either write access wasn't requested, or
1742 the file isn't read-only, or if it's a directory, as there are
1743 no read-only directories on Windows. */
1744 return PyBool_FromLong(!(mode & 2)
1745 || !(attr & FILE_ATTRIBUTE_READONLY)
1746 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001747#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001748 int res;
1749 if (!PyArg_ParseTuple(args, "O&i:access",
1750 PyUnicode_FSConverter, &opath, &mode))
1751 return NULL;
1752 path = PyBytes_AsString(opath);
1753 Py_BEGIN_ALLOW_THREADS
1754 res = access(path, mode);
1755 Py_END_ALLOW_THREADS
1756 Py_DECREF(opath);
1757 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001758#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001759}
1760
Guido van Rossumd371ff11999-01-25 16:12:23 +00001761#ifndef F_OK
1762#define F_OK 0
1763#endif
1764#ifndef R_OK
1765#define R_OK 4
1766#endif
1767#ifndef W_OK
1768#define W_OK 2
1769#endif
1770#ifndef X_OK
1771#define X_OK 1
1772#endif
1773
1774#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001775PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001776"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001777Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001778
1779static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001780posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001781{
Victor Stinner8c62be82010-05-06 00:08:46 +00001782 int id;
1783 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001784
Victor Stinner8c62be82010-05-06 00:08:46 +00001785 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1786 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001787
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001788#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001789 /* file descriptor 0 only, the default input device (stdin) */
1790 if (id == 0) {
1791 ret = ttyname();
1792 }
1793 else {
1794 ret = NULL;
1795 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001796#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001797 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001798#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001799 if (ret == NULL)
1800 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001801 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001802}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001803#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001804
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001805#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001806PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001807"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001808Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001809
1810static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001811posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001812{
Victor Stinner8c62be82010-05-06 00:08:46 +00001813 char *ret;
1814 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001815
Greg Wardb48bc172000-03-01 21:51:56 +00001816#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001817 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001818#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001819 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001820#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001821 if (ret == NULL)
1822 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001823 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001824}
1825#endif
1826
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001827PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001828"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001829Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001830
Barry Warsaw53699e91996-12-10 23:23:01 +00001831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001832posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001833{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001834#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001835 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001836#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001837 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001838#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001839 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001840#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001841 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001842#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001843}
1844
Fred Drake4d1e64b2002-04-15 19:40:07 +00001845#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001846PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001847"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001848Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001849opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001850
1851static PyObject *
1852posix_fchdir(PyObject *self, PyObject *fdobj)
1853{
Victor Stinner8c62be82010-05-06 00:08:46 +00001854 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001855}
1856#endif /* HAVE_FCHDIR */
1857
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001858
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001859PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001860"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001861Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001862
Barry Warsaw53699e91996-12-10 23:23:01 +00001863static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001864posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001865{
Victor Stinner8c62be82010-05-06 00:08:46 +00001866 PyObject *opath = NULL;
1867 char *path = NULL;
1868 int i;
1869 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001870#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001871 DWORD attr;
1872 PyUnicodeObject *po;
1873 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1874 Py_BEGIN_ALLOW_THREADS
1875 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1876 if (attr != 0xFFFFFFFF) {
1877 if (i & _S_IWRITE)
1878 attr &= ~FILE_ATTRIBUTE_READONLY;
1879 else
1880 attr |= FILE_ATTRIBUTE_READONLY;
1881 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1882 }
1883 else
1884 res = 0;
1885 Py_END_ALLOW_THREADS
1886 if (!res)
1887 return win32_error_unicode("chmod",
1888 PyUnicode_AS_UNICODE(po));
1889 Py_INCREF(Py_None);
1890 return Py_None;
1891 }
1892 /* Drop the argument parsing error as narrow strings
1893 are also valid. */
1894 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001895
Victor Stinner8c62be82010-05-06 00:08:46 +00001896 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1897 &opath, &i))
1898 return NULL;
1899 path = PyBytes_AsString(opath);
1900 Py_BEGIN_ALLOW_THREADS
1901 attr = GetFileAttributesA(path);
1902 if (attr != 0xFFFFFFFF) {
1903 if (i & _S_IWRITE)
1904 attr &= ~FILE_ATTRIBUTE_READONLY;
1905 else
1906 attr |= FILE_ATTRIBUTE_READONLY;
1907 res = SetFileAttributesA(path, attr);
1908 }
1909 else
1910 res = 0;
1911 Py_END_ALLOW_THREADS
1912 if (!res) {
1913 win32_error("chmod", path);
1914 Py_DECREF(opath);
1915 return NULL;
1916 }
1917 Py_DECREF(opath);
1918 Py_INCREF(Py_None);
1919 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001920#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00001921 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1922 &opath, &i))
1923 return NULL;
1924 path = PyBytes_AsString(opath);
1925 Py_BEGIN_ALLOW_THREADS
1926 res = chmod(path, i);
1927 Py_END_ALLOW_THREADS
1928 if (res < 0)
1929 return posix_error_with_allocated_filename(opath);
1930 Py_DECREF(opath);
1931 Py_INCREF(Py_None);
1932 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001933#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001934}
1935
Christian Heimes4e30a842007-11-30 22:12:06 +00001936#ifdef HAVE_FCHMOD
1937PyDoc_STRVAR(posix_fchmod__doc__,
1938"fchmod(fd, mode)\n\n\
1939Change the access permissions of the file given by file\n\
1940descriptor fd.");
1941
1942static PyObject *
1943posix_fchmod(PyObject *self, PyObject *args)
1944{
Victor Stinner8c62be82010-05-06 00:08:46 +00001945 int fd, mode, res;
1946 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1947 return NULL;
1948 Py_BEGIN_ALLOW_THREADS
1949 res = fchmod(fd, mode);
1950 Py_END_ALLOW_THREADS
1951 if (res < 0)
1952 return posix_error();
1953 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001954}
1955#endif /* HAVE_FCHMOD */
1956
1957#ifdef HAVE_LCHMOD
1958PyDoc_STRVAR(posix_lchmod__doc__,
1959"lchmod(path, mode)\n\n\
1960Change the access permissions of a file. If path is a symlink, this\n\
1961affects the link itself rather than the target.");
1962
1963static PyObject *
1964posix_lchmod(PyObject *self, PyObject *args)
1965{
Victor Stinner8c62be82010-05-06 00:08:46 +00001966 PyObject *opath;
1967 char *path;
1968 int i;
1969 int res;
1970 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
1971 &opath, &i))
1972 return NULL;
1973 path = PyBytes_AsString(opath);
1974 Py_BEGIN_ALLOW_THREADS
1975 res = lchmod(path, i);
1976 Py_END_ALLOW_THREADS
1977 if (res < 0)
1978 return posix_error_with_allocated_filename(opath);
1979 Py_DECREF(opath);
1980 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00001981}
1982#endif /* HAVE_LCHMOD */
1983
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001984
Thomas Wouterscf297e42007-02-23 15:07:44 +00001985#ifdef HAVE_CHFLAGS
1986PyDoc_STRVAR(posix_chflags__doc__,
1987"chflags(path, flags)\n\n\
1988Set file flags.");
1989
1990static PyObject *
1991posix_chflags(PyObject *self, PyObject *args)
1992{
Victor Stinner8c62be82010-05-06 00:08:46 +00001993 PyObject *opath;
1994 char *path;
1995 unsigned long flags;
1996 int res;
1997 if (!PyArg_ParseTuple(args, "O&k:chflags",
1998 PyUnicode_FSConverter, &opath, &flags))
1999 return NULL;
2000 path = PyBytes_AsString(opath);
2001 Py_BEGIN_ALLOW_THREADS
2002 res = chflags(path, flags);
2003 Py_END_ALLOW_THREADS
2004 if (res < 0)
2005 return posix_error_with_allocated_filename(opath);
2006 Py_DECREF(opath);
2007 Py_INCREF(Py_None);
2008 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002009}
2010#endif /* HAVE_CHFLAGS */
2011
2012#ifdef HAVE_LCHFLAGS
2013PyDoc_STRVAR(posix_lchflags__doc__,
2014"lchflags(path, flags)\n\n\
2015Set file flags.\n\
2016This function will not follow symbolic links.");
2017
2018static PyObject *
2019posix_lchflags(PyObject *self, PyObject *args)
2020{
Victor Stinner8c62be82010-05-06 00:08:46 +00002021 PyObject *opath;
2022 char *path;
2023 unsigned long flags;
2024 int res;
2025 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2026 PyUnicode_FSConverter, &opath, &flags))
2027 return NULL;
2028 path = PyBytes_AsString(opath);
2029 Py_BEGIN_ALLOW_THREADS
2030 res = lchflags(path, flags);
2031 Py_END_ALLOW_THREADS
2032 if (res < 0)
2033 return posix_error_with_allocated_filename(opath);
2034 Py_DECREF(opath);
2035 Py_INCREF(Py_None);
2036 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002037}
2038#endif /* HAVE_LCHFLAGS */
2039
Martin v. Löwis244edc82001-10-04 22:44:26 +00002040#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002041PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002042"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002043Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002044
2045static PyObject *
2046posix_chroot(PyObject *self, PyObject *args)
2047{
Victor Stinner8c62be82010-05-06 00:08:46 +00002048 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002049}
2050#endif
2051
Guido van Rossum21142a01999-01-08 21:05:37 +00002052#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002053PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002054"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002055force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002056
2057static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002058posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002059{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002060 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002061}
2062#endif /* HAVE_FSYNC */
2063
2064#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002065
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002066#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002067extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2068#endif
2069
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002070PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002071"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002072force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002073 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002074
2075static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002076posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002077{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002078 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002079}
2080#endif /* HAVE_FDATASYNC */
2081
2082
Fredrik Lundh10723342000-07-10 16:38:09 +00002083#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002084PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002085"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002086Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002087
Barry Warsaw53699e91996-12-10 23:23:01 +00002088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002089posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002090{
Victor Stinner8c62be82010-05-06 00:08:46 +00002091 PyObject *opath;
2092 char *path;
2093 long uid, gid;
2094 int res;
2095 if (!PyArg_ParseTuple(args, "O&ll:chown",
2096 PyUnicode_FSConverter, &opath,
2097 &uid, &gid))
2098 return NULL;
2099 path = PyBytes_AsString(opath);
2100 Py_BEGIN_ALLOW_THREADS
2101 res = chown(path, (uid_t) uid, (gid_t) gid);
2102 Py_END_ALLOW_THREADS
2103 if (res < 0)
2104 return posix_error_with_allocated_filename(opath);
2105 Py_DECREF(opath);
2106 Py_INCREF(Py_None);
2107 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002108}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002109#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002110
Christian Heimes4e30a842007-11-30 22:12:06 +00002111#ifdef HAVE_FCHOWN
2112PyDoc_STRVAR(posix_fchown__doc__,
2113"fchown(fd, uid, gid)\n\n\
2114Change the owner and group id of the file given by file descriptor\n\
2115fd to the numeric uid and gid.");
2116
2117static PyObject *
2118posix_fchown(PyObject *self, PyObject *args)
2119{
Victor Stinner8c62be82010-05-06 00:08:46 +00002120 int fd;
2121 long uid, gid;
2122 int res;
2123 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2124 return NULL;
2125 Py_BEGIN_ALLOW_THREADS
2126 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2127 Py_END_ALLOW_THREADS
2128 if (res < 0)
2129 return posix_error();
2130 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002131}
2132#endif /* HAVE_FCHOWN */
2133
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002134#ifdef HAVE_LCHOWN
2135PyDoc_STRVAR(posix_lchown__doc__,
2136"lchown(path, uid, gid)\n\n\
2137Change the owner and group id of path to the numeric uid and gid.\n\
2138This function will not follow symbolic links.");
2139
2140static PyObject *
2141posix_lchown(PyObject *self, PyObject *args)
2142{
Victor Stinner8c62be82010-05-06 00:08:46 +00002143 PyObject *opath;
2144 char *path;
2145 long uid, gid;
2146 int res;
2147 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2148 PyUnicode_FSConverter, &opath,
2149 &uid, &gid))
2150 return NULL;
2151 path = PyBytes_AsString(opath);
2152 Py_BEGIN_ALLOW_THREADS
2153 res = lchown(path, (uid_t) uid, (gid_t) gid);
2154 Py_END_ALLOW_THREADS
2155 if (res < 0)
2156 return posix_error_with_allocated_filename(opath);
2157 Py_DECREF(opath);
2158 Py_INCREF(Py_None);
2159 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002160}
2161#endif /* HAVE_LCHOWN */
2162
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002163
Guido van Rossum36bc6801995-06-14 22:54:23 +00002164#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002165static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002166posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002167{
Victor Stinner8c62be82010-05-06 00:08:46 +00002168 char buf[1026];
2169 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002170
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002171#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002172 if (!use_bytes) {
2173 wchar_t wbuf[1026];
2174 wchar_t *wbuf2 = wbuf;
2175 PyObject *resobj;
2176 DWORD len;
2177 Py_BEGIN_ALLOW_THREADS
2178 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2179 /* If the buffer is large enough, len does not include the
2180 terminating \0. If the buffer is too small, len includes
2181 the space needed for the terminator. */
2182 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2183 wbuf2 = malloc(len * sizeof(wchar_t));
2184 if (wbuf2)
2185 len = GetCurrentDirectoryW(len, wbuf2);
2186 }
2187 Py_END_ALLOW_THREADS
2188 if (!wbuf2) {
2189 PyErr_NoMemory();
2190 return NULL;
2191 }
2192 if (!len) {
2193 if (wbuf2 != wbuf) free(wbuf2);
2194 return win32_error("getcwdu", NULL);
2195 }
2196 resobj = PyUnicode_FromWideChar(wbuf2, len);
2197 if (wbuf2 != wbuf) free(wbuf2);
2198 return resobj;
2199 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002200#endif
2201
Victor Stinner8c62be82010-05-06 00:08:46 +00002202 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002203#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002204 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002205#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002206 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002207#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002208 Py_END_ALLOW_THREADS
2209 if (res == NULL)
2210 return posix_error();
2211 if (use_bytes)
2212 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002213 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002214}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002215
2216PyDoc_STRVAR(posix_getcwd__doc__,
2217"getcwd() -> path\n\n\
2218Return a unicode string representing the current working directory.");
2219
2220static PyObject *
2221posix_getcwd_unicode(PyObject *self)
2222{
2223 return posix_getcwd(0);
2224}
2225
2226PyDoc_STRVAR(posix_getcwdb__doc__,
2227"getcwdb() -> path\n\n\
2228Return a bytes string representing the current working directory.");
2229
2230static PyObject *
2231posix_getcwd_bytes(PyObject *self)
2232{
2233 return posix_getcwd(1);
2234}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002235#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002236
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002237
Guido van Rossumb6775db1994-08-01 11:34:53 +00002238#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002239PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002240"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002241Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002242
Barry Warsaw53699e91996-12-10 23:23:01 +00002243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002244posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002245{
Victor Stinner8c62be82010-05-06 00:08:46 +00002246 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002247}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002248#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002249
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002250
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002251PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002252"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002253Return a list containing the names of the entries in the directory.\n\
2254\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002255 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002256\n\
2257The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002258entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002259
Barry Warsaw53699e91996-12-10 23:23:01 +00002260static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002261posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002262{
Victor Stinner8c62be82010-05-06 00:08:46 +00002263 /* XXX Should redo this putting the (now four) versions of opendir
2264 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002265#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002266
Victor Stinner8c62be82010-05-06 00:08:46 +00002267 PyObject *d, *v;
2268 HANDLE hFindFile;
2269 BOOL result;
2270 WIN32_FIND_DATA FileData;
2271 PyObject *opath;
2272 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2273 char *bufptr = namebuf;
2274 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002275
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002276 PyObject *po = NULL;
2277 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002278 WIN32_FIND_DATAW wFileData;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002279 Py_UNICODE *wnamebuf, *po_wchars;
2280
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002281 if (po == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002282 po_wchars = L".";
2283 len = 1;
2284 } else {
2285 po_wchars = PyUnicode_AS_UNICODE(po);
2286 len = PyUnicode_GET_SIZE(po);
2287 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002288 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002289 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2290 if (!wnamebuf) {
2291 PyErr_NoMemory();
2292 return NULL;
2293 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002294 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002295 if (len > 0) {
2296 Py_UNICODE wch = wnamebuf[len-1];
2297 if (wch != L'/' && wch != L'\\' && wch != L':')
2298 wnamebuf[len++] = L'\\';
2299 wcscpy(wnamebuf + len, L"*.*");
2300 }
2301 if ((d = PyList_New(0)) == NULL) {
2302 free(wnamebuf);
2303 return NULL;
2304 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002305 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002306 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002307 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002308 if (hFindFile == INVALID_HANDLE_VALUE) {
2309 int error = GetLastError();
2310 if (error == ERROR_FILE_NOT_FOUND) {
2311 free(wnamebuf);
2312 return d;
2313 }
2314 Py_DECREF(d);
2315 win32_error_unicode("FindFirstFileW", wnamebuf);
2316 free(wnamebuf);
2317 return NULL;
2318 }
2319 do {
2320 /* Skip over . and .. */
2321 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2322 wcscmp(wFileData.cFileName, L"..") != 0) {
2323 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2324 if (v == NULL) {
2325 Py_DECREF(d);
2326 d = NULL;
2327 break;
2328 }
2329 if (PyList_Append(d, v) != 0) {
2330 Py_DECREF(v);
2331 Py_DECREF(d);
2332 d = NULL;
2333 break;
2334 }
2335 Py_DECREF(v);
2336 }
2337 Py_BEGIN_ALLOW_THREADS
2338 result = FindNextFileW(hFindFile, &wFileData);
2339 Py_END_ALLOW_THREADS
2340 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2341 it got to the end of the directory. */
2342 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2343 Py_DECREF(d);
2344 win32_error_unicode("FindNextFileW", wnamebuf);
2345 FindClose(hFindFile);
2346 free(wnamebuf);
2347 return NULL;
2348 }
2349 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002350
Victor Stinner8c62be82010-05-06 00:08:46 +00002351 if (FindClose(hFindFile) == FALSE) {
2352 Py_DECREF(d);
2353 win32_error_unicode("FindClose", wnamebuf);
2354 free(wnamebuf);
2355 return NULL;
2356 }
2357 free(wnamebuf);
2358 return d;
2359 }
2360 /* Drop the argument parsing error as narrow strings
2361 are also valid. */
2362 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002363
Victor Stinner8c62be82010-05-06 00:08:46 +00002364 if (!PyArg_ParseTuple(args, "O&:listdir",
2365 PyUnicode_FSConverter, &opath))
2366 return NULL;
2367 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2368 PyErr_SetString(PyExc_ValueError, "path too long");
2369 Py_DECREF(opath);
2370 return NULL;
2371 }
2372 strcpy(namebuf, PyBytes_AsString(opath));
2373 len = PyObject_Size(opath);
2374 if (len > 0) {
2375 char ch = namebuf[len-1];
2376 if (ch != SEP && ch != ALTSEP && ch != ':')
2377 namebuf[len++] = '/';
2378 strcpy(namebuf + len, "*.*");
2379 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002380
Victor Stinner8c62be82010-05-06 00:08:46 +00002381 if ((d = PyList_New(0)) == NULL)
2382 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002383
Antoine Pitroub73caab2010-08-09 23:39:31 +00002384 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002385 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002386 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002387 if (hFindFile == INVALID_HANDLE_VALUE) {
2388 int error = GetLastError();
2389 if (error == ERROR_FILE_NOT_FOUND)
2390 return d;
2391 Py_DECREF(d);
2392 return win32_error("FindFirstFile", namebuf);
2393 }
2394 do {
2395 /* Skip over . and .. */
2396 if (strcmp(FileData.cFileName, ".") != 0 &&
2397 strcmp(FileData.cFileName, "..") != 0) {
2398 v = PyBytes_FromString(FileData.cFileName);
2399 if (v == NULL) {
2400 Py_DECREF(d);
2401 d = NULL;
2402 break;
2403 }
2404 if (PyList_Append(d, v) != 0) {
2405 Py_DECREF(v);
2406 Py_DECREF(d);
2407 d = NULL;
2408 break;
2409 }
2410 Py_DECREF(v);
2411 }
2412 Py_BEGIN_ALLOW_THREADS
2413 result = FindNextFile(hFindFile, &FileData);
2414 Py_END_ALLOW_THREADS
2415 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2416 it got to the end of the directory. */
2417 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2418 Py_DECREF(d);
2419 win32_error("FindNextFile", namebuf);
2420 FindClose(hFindFile);
2421 return NULL;
2422 }
2423 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002424
Victor Stinner8c62be82010-05-06 00:08:46 +00002425 if (FindClose(hFindFile) == FALSE) {
2426 Py_DECREF(d);
2427 return win32_error("FindClose", namebuf);
2428 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002429
Victor Stinner8c62be82010-05-06 00:08:46 +00002430 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002431
Tim Peters0bb44a42000-09-15 07:44:49 +00002432#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002433
2434#ifndef MAX_PATH
2435#define MAX_PATH CCHMAXPATH
2436#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002437 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002438 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002439 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002440 PyObject *d, *v;
2441 char namebuf[MAX_PATH+5];
2442 HDIR hdir = 1;
2443 ULONG srchcnt = 1;
2444 FILEFINDBUF3 ep;
2445 APIRET rc;
2446
Victor Stinner8c62be82010-05-06 00:08:46 +00002447 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002448 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002449 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002450 name = PyBytes_AsString(oname);
2451 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002452 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002453 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002454 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002455 return NULL;
2456 }
2457 strcpy(namebuf, name);
2458 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002459 if (*pt == ALTSEP)
2460 *pt = SEP;
2461 if (namebuf[len-1] != SEP)
2462 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002463 strcpy(namebuf + len, "*.*");
2464
Neal Norwitz6c913782007-10-14 03:23:09 +00002465 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002466 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002467 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002468 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002469
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002470 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2471 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002472 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002473 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2474 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2475 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002476
2477 if (rc != NO_ERROR) {
2478 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002479 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002480 }
2481
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002482 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002483 do {
2484 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002485 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002486 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002487
2488 strcpy(namebuf, ep.achName);
2489
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002490 /* Leave Case of Name Alone -- In Native Form */
2491 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002492
Christian Heimes72b710a2008-05-26 13:28:38 +00002493 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002494 if (v == NULL) {
2495 Py_DECREF(d);
2496 d = NULL;
2497 break;
2498 }
2499 if (PyList_Append(d, v) != 0) {
2500 Py_DECREF(v);
2501 Py_DECREF(d);
2502 d = NULL;
2503 break;
2504 }
2505 Py_DECREF(v);
2506 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2507 }
2508
Victor Stinnerdcb24032010-04-22 12:08:36 +00002509 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002510 return d;
2511#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002512 PyObject *oname;
2513 char *name;
2514 PyObject *d, *v;
2515 DIR *dirp;
2516 struct dirent *ep;
2517 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002518
Victor Stinner8c62be82010-05-06 00:08:46 +00002519 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002520 /* v is never read, so it does not need to be initialized yet. */
2521 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002522 arg_is_unicode = 0;
2523 PyErr_Clear();
2524 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002525 oname = NULL;
2526 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002527 return NULL;
Antoine Pitrou3d330ad2010-09-14 10:08:08 +00002528 if (oname == NULL) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002529 oname = PyBytes_FromString(".");
2530 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002531 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002532 Py_BEGIN_ALLOW_THREADS
2533 dirp = opendir(name);
2534 Py_END_ALLOW_THREADS
2535 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002536 return posix_error_with_allocated_filename(oname);
2537 }
2538 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002539 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002540 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002541 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002542 Py_DECREF(oname);
2543 return NULL;
2544 }
2545 for (;;) {
2546 errno = 0;
2547 Py_BEGIN_ALLOW_THREADS
2548 ep = readdir(dirp);
2549 Py_END_ALLOW_THREADS
2550 if (ep == NULL) {
2551 if (errno == 0) {
2552 break;
2553 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002554 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002555 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002556 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002557 Py_DECREF(d);
2558 return posix_error_with_allocated_filename(oname);
2559 }
2560 }
2561 if (ep->d_name[0] == '.' &&
2562 (NAMLEN(ep) == 1 ||
2563 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2564 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002565 if (arg_is_unicode)
2566 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2567 else
2568 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002569 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002570 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002571 break;
2572 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002573 if (PyList_Append(d, v) != 0) {
2574 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002575 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002576 break;
2577 }
2578 Py_DECREF(v);
2579 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002580 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002581 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002582 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002583 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002584
Victor Stinner8c62be82010-05-06 00:08:46 +00002585 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002586
Tim Peters0bb44a42000-09-15 07:44:49 +00002587#endif /* which OS */
2588} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002589
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002590#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002591/* A helper function for abspath on win32 */
2592static PyObject *
2593posix__getfullpathname(PyObject *self, PyObject *args)
2594{
Victor Stinner8c62be82010-05-06 00:08:46 +00002595 PyObject *opath;
2596 char *path;
2597 char outbuf[MAX_PATH*2];
2598 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002599#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002600 PyUnicodeObject *po;
2601 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2602 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2603 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2604 Py_UNICODE *wtemp;
2605 DWORD result;
2606 PyObject *v;
2607 result = GetFullPathNameW(wpath,
2608 sizeof(woutbuf)/sizeof(woutbuf[0]),
2609 woutbuf, &wtemp);
2610 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2611 woutbufp = malloc(result * sizeof(Py_UNICODE));
2612 if (!woutbufp)
2613 return PyErr_NoMemory();
2614 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2615 }
2616 if (result)
2617 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2618 else
2619 v = win32_error_unicode("GetFullPathNameW", wpath);
2620 if (woutbufp != woutbuf)
2621 free(woutbufp);
2622 return v;
2623 }
2624 /* Drop the argument parsing error as narrow strings
2625 are also valid. */
2626 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002627
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002628#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002629 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2630 PyUnicode_FSConverter, &opath))
2631 return NULL;
2632 path = PyBytes_AsString(opath);
2633 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2634 outbuf, &temp)) {
2635 win32_error("GetFullPathName", path);
2636 Py_DECREF(opath);
2637 return NULL;
2638 }
2639 Py_DECREF(opath);
2640 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2641 return PyUnicode_Decode(outbuf, strlen(outbuf),
2642 Py_FileSystemDefaultEncoding, NULL);
2643 }
2644 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002645} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002646
2647/* A helper function for samepath on windows */
2648static PyObject *
2649posix__getfinalpathname(PyObject *self, PyObject *args)
2650{
2651 HANDLE hFile;
2652 int buf_size;
2653 wchar_t *target_path;
2654 int result_length;
2655 PyObject *result;
2656 wchar_t *path;
2657
Brian Curtin94622b02010-09-24 00:03:39 +00002658 if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) {
Brian Curtind40e6f72010-07-08 21:39:08 +00002659 return NULL;
2660 }
2661
2662 if(!check_GetFinalPathNameByHandle()) {
2663 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2664 NotImplementedError. */
2665 return PyErr_Format(PyExc_NotImplementedError,
2666 "GetFinalPathNameByHandle not available on this platform");
2667 }
2668
2669 hFile = CreateFileW(
2670 path,
2671 0, /* desired access */
2672 0, /* share mode */
2673 NULL, /* security attributes */
2674 OPEN_EXISTING,
2675 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2676 FILE_FLAG_BACKUP_SEMANTICS,
2677 NULL);
2678
2679 if(hFile == INVALID_HANDLE_VALUE) {
2680 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002681 return PyErr_Format(PyExc_RuntimeError,
2682 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002683 }
2684
2685 /* We have a good handle to the target, use it to determine the
2686 target path name. */
2687 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2688
2689 if(!buf_size)
2690 return win32_error_unicode("GetFinalPathNameByHandle", path);
2691
2692 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2693 if(!target_path)
2694 return PyErr_NoMemory();
2695
2696 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2697 buf_size, VOLUME_NAME_DOS);
2698 if(!result_length)
2699 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2700
2701 if(!CloseHandle(hFile))
2702 return win32_error_unicode("GetFinalPathNameByHandle", path);
2703
2704 target_path[result_length] = 0;
2705 result = PyUnicode_FromUnicode(target_path, result_length);
2706 free(target_path);
2707 return result;
2708
2709} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00002710
2711static PyObject *
2712posix__getfileinformation(PyObject *self, PyObject *args)
2713{
2714 HANDLE hFile;
2715 BY_HANDLE_FILE_INFORMATION info;
2716 int fd;
2717
2718 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
2719 return NULL;
2720
2721 if (!_PyVerify_fd(fd)) {
2722 PyErr_SetString(PyExc_ValueError, "received invalid file descriptor");
2723 return NULL;
2724 }
2725
2726 hFile = (HANDLE)_get_osfhandle(fd);
2727 if (hFile == INVALID_HANDLE_VALUE)
2728 return win32_error("_getfileinformation", NULL);
2729
2730 if (!GetFileInformationByHandle(hFile, &info))
2731 return win32_error("_getfileinformation", NULL);
2732
2733 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
2734 info.nFileIndexHigh,
2735 info.nFileIndexLow);
2736}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002737#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002738
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002739PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002740"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002741Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002742
Barry Warsaw53699e91996-12-10 23:23:01 +00002743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002744posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002745{
Victor Stinner8c62be82010-05-06 00:08:46 +00002746 int res;
2747 PyObject *opath;
2748 char *path;
2749 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002750
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002751#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002752 PyUnicodeObject *po;
2753 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2754 Py_BEGIN_ALLOW_THREADS
2755 /* PyUnicode_AS_UNICODE OK without thread lock as
2756 it is a simple dereference. */
2757 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2758 Py_END_ALLOW_THREADS
2759 if (!res)
2760 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2761 Py_INCREF(Py_None);
2762 return Py_None;
2763 }
2764 /* Drop the argument parsing error as narrow strings
2765 are also valid. */
2766 PyErr_Clear();
2767 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2768 PyUnicode_FSConverter, &opath, &mode))
2769 return NULL;
2770 path = PyBytes_AsString(opath);
2771 Py_BEGIN_ALLOW_THREADS
2772 /* PyUnicode_AS_UNICODE OK without thread lock as
2773 it is a simple dereference. */
2774 res = CreateDirectoryA(path, NULL);
2775 Py_END_ALLOW_THREADS
2776 if (!res) {
2777 win32_error("mkdir", path);
2778 Py_DECREF(opath);
2779 return NULL;
2780 }
2781 Py_DECREF(opath);
2782 Py_INCREF(Py_None);
2783 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002784#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002785
Victor Stinner8c62be82010-05-06 00:08:46 +00002786 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2787 PyUnicode_FSConverter, &opath, &mode))
2788 return NULL;
2789 path = PyBytes_AsString(opath);
2790 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002791#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002792 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002793#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002794 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002795#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002796 Py_END_ALLOW_THREADS
2797 if (res < 0)
2798 return posix_error_with_allocated_filename(opath);
2799 Py_DECREF(opath);
2800 Py_INCREF(Py_None);
2801 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002802#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002803}
2804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002805
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002806/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2807#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002808#include <sys/resource.h>
2809#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002810
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002811
2812#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002813PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002814"nice(inc) -> new_priority\n\n\
2815Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002816
Barry Warsaw53699e91996-12-10 23:23:01 +00002817static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002818posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002819{
Victor Stinner8c62be82010-05-06 00:08:46 +00002820 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002821
Victor Stinner8c62be82010-05-06 00:08:46 +00002822 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2823 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002824
Victor Stinner8c62be82010-05-06 00:08:46 +00002825 /* There are two flavours of 'nice': one that returns the new
2826 priority (as required by almost all standards out there) and the
2827 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2828 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002829
Victor Stinner8c62be82010-05-06 00:08:46 +00002830 If we are of the nice family that returns the new priority, we
2831 need to clear errno before the call, and check if errno is filled
2832 before calling posix_error() on a returnvalue of -1, because the
2833 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002834
Victor Stinner8c62be82010-05-06 00:08:46 +00002835 errno = 0;
2836 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002837#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00002838 if (value == 0)
2839 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002840#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002841 if (value == -1 && errno != 0)
2842 /* either nice() or getpriority() returned an error */
2843 return posix_error();
2844 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002845}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002846#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002847
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002848PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002849"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002850Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002851
Barry Warsaw53699e91996-12-10 23:23:01 +00002852static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002853posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002854{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002855#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002856 PyObject *o1, *o2;
2857 char *p1, *p2;
2858 BOOL result;
2859 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2860 goto error;
2861 if (!convert_to_unicode(&o1))
2862 goto error;
2863 if (!convert_to_unicode(&o2)) {
2864 Py_DECREF(o1);
2865 goto error;
2866 }
2867 Py_BEGIN_ALLOW_THREADS
2868 result = MoveFileW(PyUnicode_AsUnicode(o1),
2869 PyUnicode_AsUnicode(o2));
2870 Py_END_ALLOW_THREADS
2871 Py_DECREF(o1);
2872 Py_DECREF(o2);
2873 if (!result)
2874 return win32_error("rename", NULL);
2875 Py_INCREF(Py_None);
2876 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002877error:
Victor Stinner8c62be82010-05-06 00:08:46 +00002878 PyErr_Clear();
2879 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2880 return NULL;
2881 Py_BEGIN_ALLOW_THREADS
2882 result = MoveFileA(p1, p2);
2883 Py_END_ALLOW_THREADS
2884 if (!result)
2885 return win32_error("rename", NULL);
2886 Py_INCREF(Py_None);
2887 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002888#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002889 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002890#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002891}
2892
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002893
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002894PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002895"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002896Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002897
Barry Warsaw53699e91996-12-10 23:23:01 +00002898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002899posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002900{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002901#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002902 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002903#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002904 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002905#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002906}
2907
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002908
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002909PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002910"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002911Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002912
Barry Warsaw53699e91996-12-10 23:23:01 +00002913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002914posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002915{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002916#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00002917 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002918#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002919 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002920#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002921}
2922
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002923
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002924#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002925PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002926"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002927Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002928
Barry Warsaw53699e91996-12-10 23:23:01 +00002929static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002930posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002931{
Victor Stinner8c62be82010-05-06 00:08:46 +00002932 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002933#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002934 wchar_t *command;
2935 if (!PyArg_ParseTuple(args, "u:system", &command))
2936 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002937
Victor Stinner8c62be82010-05-06 00:08:46 +00002938 Py_BEGIN_ALLOW_THREADS
2939 sts = _wsystem(command);
2940 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00002941#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002942 PyObject *command_obj;
2943 char *command;
2944 if (!PyArg_ParseTuple(args, "O&:system",
2945 PyUnicode_FSConverter, &command_obj))
2946 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002947
Victor Stinner8c62be82010-05-06 00:08:46 +00002948 command = PyBytes_AsString(command_obj);
2949 Py_BEGIN_ALLOW_THREADS
2950 sts = system(command);
2951 Py_END_ALLOW_THREADS
2952 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00002953#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002954 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002955}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002956#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002957
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002958
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002959PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002960"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002961Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002962
Barry Warsaw53699e91996-12-10 23:23:01 +00002963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002964posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002965{
Victor Stinner8c62be82010-05-06 00:08:46 +00002966 int i;
2967 if (!PyArg_ParseTuple(args, "i:umask", &i))
2968 return NULL;
2969 i = (int)umask(i);
2970 if (i < 0)
2971 return posix_error();
2972 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002973}
2974
Brian Curtind40e6f72010-07-08 21:39:08 +00002975#ifdef MS_WINDOWS
2976
2977/* override the default DeleteFileW behavior so that directory
2978symlinks can be removed with this function, the same as with
2979Unix symlinks */
2980BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
2981{
2982 WIN32_FILE_ATTRIBUTE_DATA info;
2983 WIN32_FIND_DATAW find_data;
2984 HANDLE find_data_handle;
2985 int is_directory = 0;
2986 int is_link = 0;
2987
2988 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
2989 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
2990
2991 /* Get WIN32_FIND_DATA structure for the path to determine if
2992 it is a symlink */
2993 if(is_directory &&
2994 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
2995 find_data_handle = FindFirstFileW(lpFileName, &find_data);
2996
2997 if(find_data_handle != INVALID_HANDLE_VALUE) {
2998 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
2999 FindClose(find_data_handle);
3000 }
3001 }
3002 }
3003
3004 if (is_directory && is_link)
3005 return RemoveDirectoryW(lpFileName);
3006
3007 return DeleteFileW(lpFileName);
3008}
3009#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003010
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003011PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003012"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003013Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003014
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003015PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003016"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003017Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003018
Barry Warsaw53699e91996-12-10 23:23:01 +00003019static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003020posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003021{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003022#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003023 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3024 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003025#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003026 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003027#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003028}
3029
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003030
Guido van Rossumb6775db1994-08-01 11:34:53 +00003031#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003032PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003033"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003034Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003035
Barry Warsaw53699e91996-12-10 23:23:01 +00003036static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003037posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003038{
Victor Stinner8c62be82010-05-06 00:08:46 +00003039 struct utsname u;
3040 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003041
Victor Stinner8c62be82010-05-06 00:08:46 +00003042 Py_BEGIN_ALLOW_THREADS
3043 res = uname(&u);
3044 Py_END_ALLOW_THREADS
3045 if (res < 0)
3046 return posix_error();
3047 return Py_BuildValue("(sssss)",
3048 u.sysname,
3049 u.nodename,
3050 u.release,
3051 u.version,
3052 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003053}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003054#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003055
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003056static int
3057extract_time(PyObject *t, long* sec, long* usec)
3058{
Victor Stinner8c62be82010-05-06 00:08:46 +00003059 long intval;
3060 if (PyFloat_Check(t)) {
3061 double tval = PyFloat_AsDouble(t);
3062 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
3063 if (!intobj)
3064 return -1;
3065 intval = PyLong_AsLong(intobj);
3066 Py_DECREF(intobj);
3067 if (intval == -1 && PyErr_Occurred())
3068 return -1;
3069 *sec = intval;
3070 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3071 if (*usec < 0)
3072 /* If rounding gave us a negative number,
3073 truncate. */
3074 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003075 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003076 }
3077 intval = PyLong_AsLong(t);
3078 if (intval == -1 && PyErr_Occurred())
3079 return -1;
3080 *sec = intval;
3081 *usec = 0;
3082 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003083}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003084
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003085PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003086"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003087utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003088Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003089second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003090
Barry Warsaw53699e91996-12-10 23:23:01 +00003091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003092posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003093{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003094#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003095 PyObject *arg;
3096 PyUnicodeObject *obwpath;
3097 wchar_t *wpath = NULL;
3098 PyObject *oapath;
3099 char *apath;
3100 HANDLE hFile;
3101 long atimesec, mtimesec, ausec, musec;
3102 FILETIME atime, mtime;
3103 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003104
Victor Stinner8c62be82010-05-06 00:08:46 +00003105 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3106 wpath = PyUnicode_AS_UNICODE(obwpath);
3107 Py_BEGIN_ALLOW_THREADS
3108 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3109 NULL, OPEN_EXISTING,
3110 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3111 Py_END_ALLOW_THREADS
3112 if (hFile == INVALID_HANDLE_VALUE)
3113 return win32_error_unicode("utime", wpath);
3114 } else
3115 /* Drop the argument parsing error as narrow strings
3116 are also valid. */
3117 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003118
Victor Stinner8c62be82010-05-06 00:08:46 +00003119 if (!wpath) {
3120 if (!PyArg_ParseTuple(args, "O&O:utime",
3121 PyUnicode_FSConverter, &oapath, &arg))
3122 return NULL;
3123 apath = PyBytes_AsString(oapath);
3124 Py_BEGIN_ALLOW_THREADS
3125 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3126 NULL, OPEN_EXISTING,
3127 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3128 Py_END_ALLOW_THREADS
3129 if (hFile == INVALID_HANDLE_VALUE) {
3130 win32_error("utime", apath);
3131 Py_DECREF(oapath);
3132 return NULL;
3133 }
3134 Py_DECREF(oapath);
3135 }
3136
3137 if (arg == Py_None) {
3138 SYSTEMTIME now;
3139 GetSystemTime(&now);
3140 if (!SystemTimeToFileTime(&now, &mtime) ||
3141 !SystemTimeToFileTime(&now, &atime)) {
3142 win32_error("utime", NULL);
3143 goto done;
3144 }
3145 }
3146 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3147 PyErr_SetString(PyExc_TypeError,
3148 "utime() arg 2 must be a tuple (atime, mtime)");
3149 goto done;
3150 }
3151 else {
3152 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3153 &atimesec, &ausec) == -1)
3154 goto done;
3155 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3156 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3157 &mtimesec, &musec) == -1)
3158 goto done;
3159 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3160 }
3161 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3162 /* Avoid putting the file name into the error here,
3163 as that may confuse the user into believing that
3164 something is wrong with the file, when it also
3165 could be the time stamp that gives a problem. */
3166 win32_error("utime", NULL);
3167 }
3168 Py_INCREF(Py_None);
3169 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003170done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003171 CloseHandle(hFile);
3172 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003173#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003174
Victor Stinner8c62be82010-05-06 00:08:46 +00003175 PyObject *opath;
3176 char *path;
3177 long atime, mtime, ausec, musec;
3178 int res;
3179 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003180
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003181#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003182 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003183#define ATIME buf[0].tv_sec
3184#define MTIME buf[1].tv_sec
3185#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003186/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003187 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003188#define ATIME buf.actime
3189#define MTIME buf.modtime
3190#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003191#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003192 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003193#define ATIME buf[0]
3194#define MTIME buf[1]
3195#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003196#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003197
Mark Hammond817c9292003-12-03 01:22:38 +00003198
Victor Stinner8c62be82010-05-06 00:08:46 +00003199 if (!PyArg_ParseTuple(args, "O&O:utime",
3200 PyUnicode_FSConverter, &opath, &arg))
3201 return NULL;
3202 path = PyBytes_AsString(opath);
3203 if (arg == Py_None) {
3204 /* optional time values not given */
3205 Py_BEGIN_ALLOW_THREADS
3206 res = utime(path, NULL);
3207 Py_END_ALLOW_THREADS
3208 }
3209 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3210 PyErr_SetString(PyExc_TypeError,
3211 "utime() arg 2 must be a tuple (atime, mtime)");
3212 Py_DECREF(opath);
3213 return NULL;
3214 }
3215 else {
3216 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3217 &atime, &ausec) == -1) {
3218 Py_DECREF(opath);
3219 return NULL;
3220 }
3221 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3222 &mtime, &musec) == -1) {
3223 Py_DECREF(opath);
3224 return NULL;
3225 }
3226 ATIME = atime;
3227 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003228#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003229 buf[0].tv_usec = ausec;
3230 buf[1].tv_usec = musec;
3231 Py_BEGIN_ALLOW_THREADS
3232 res = utimes(path, buf);
3233 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003234#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 Py_BEGIN_ALLOW_THREADS
3236 res = utime(path, UTIME_ARG);
3237 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003238#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003239 }
3240 if (res < 0) {
3241 return posix_error_with_allocated_filename(opath);
3242 }
3243 Py_DECREF(opath);
3244 Py_INCREF(Py_None);
3245 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003246#undef UTIME_ARG
3247#undef ATIME
3248#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003249#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003250}
3251
Guido van Rossum85e3b011991-06-03 12:42:10 +00003252
Guido van Rossum3b066191991-06-04 19:40:25 +00003253/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003254
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003255PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003256"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003257Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003258
Barry Warsaw53699e91996-12-10 23:23:01 +00003259static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003260posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003261{
Victor Stinner8c62be82010-05-06 00:08:46 +00003262 int sts;
3263 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3264 return NULL;
3265 _exit(sts);
3266 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003267}
3268
Martin v. Löwis114619e2002-10-07 06:44:21 +00003269#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3270static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003271free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003272{
Victor Stinner8c62be82010-05-06 00:08:46 +00003273 Py_ssize_t i;
3274 for (i = 0; i < count; i++)
3275 PyMem_Free(array[i]);
3276 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003277}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003278
Antoine Pitrou69f71142009-05-24 21:25:49 +00003279static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003280int fsconvert_strdup(PyObject *o, char**out)
3281{
Victor Stinner8c62be82010-05-06 00:08:46 +00003282 PyObject *bytes;
3283 Py_ssize_t size;
3284 if (!PyUnicode_FSConverter(o, &bytes))
3285 return 0;
3286 size = PyBytes_GET_SIZE(bytes);
3287 *out = PyMem_Malloc(size+1);
3288 if (!*out)
3289 return 0;
3290 memcpy(*out, PyBytes_AsString(bytes), size+1);
3291 Py_DECREF(bytes);
3292 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003293}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003294#endif
3295
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003296
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003297#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003298PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003299"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003300Execute an executable path with arguments, replacing current process.\n\
3301\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003302 path: path of executable file\n\
3303 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003304
Barry Warsaw53699e91996-12-10 23:23:01 +00003305static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003306posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003307{
Victor Stinner8c62be82010-05-06 00:08:46 +00003308 PyObject *opath;
3309 char *path;
3310 PyObject *argv;
3311 char **argvlist;
3312 Py_ssize_t i, argc;
3313 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003314
Victor Stinner8c62be82010-05-06 00:08:46 +00003315 /* execv has two arguments: (path, argv), where
3316 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003317
Victor Stinner8c62be82010-05-06 00:08:46 +00003318 if (!PyArg_ParseTuple(args, "O&O:execv",
3319 PyUnicode_FSConverter,
3320 &opath, &argv))
3321 return NULL;
3322 path = PyBytes_AsString(opath);
3323 if (PyList_Check(argv)) {
3324 argc = PyList_Size(argv);
3325 getitem = PyList_GetItem;
3326 }
3327 else if (PyTuple_Check(argv)) {
3328 argc = PyTuple_Size(argv);
3329 getitem = PyTuple_GetItem;
3330 }
3331 else {
3332 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3333 Py_DECREF(opath);
3334 return NULL;
3335 }
3336 if (argc < 1) {
3337 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3338 Py_DECREF(opath);
3339 return NULL;
3340 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003341
Victor Stinner8c62be82010-05-06 00:08:46 +00003342 argvlist = PyMem_NEW(char *, argc+1);
3343 if (argvlist == NULL) {
3344 Py_DECREF(opath);
3345 return PyErr_NoMemory();
3346 }
3347 for (i = 0; i < argc; i++) {
3348 if (!fsconvert_strdup((*getitem)(argv, i),
3349 &argvlist[i])) {
3350 free_string_array(argvlist, i);
3351 PyErr_SetString(PyExc_TypeError,
3352 "execv() arg 2 must contain only strings");
3353 Py_DECREF(opath);
3354 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003355
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 }
3357 }
3358 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003359
Victor Stinner8c62be82010-05-06 00:08:46 +00003360 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003361
Victor Stinner8c62be82010-05-06 00:08:46 +00003362 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003363
Victor Stinner8c62be82010-05-06 00:08:46 +00003364 free_string_array(argvlist, argc);
3365 Py_DECREF(opath);
3366 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003367}
3368
Victor Stinner13bb71c2010-04-23 21:41:56 +00003369static char**
3370parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3371{
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 char **envlist;
3373 Py_ssize_t i, pos, envc;
3374 PyObject *keys=NULL, *vals=NULL;
3375 PyObject *key, *val, *key2, *val2;
3376 char *p, *k, *v;
3377 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003378
Victor Stinner8c62be82010-05-06 00:08:46 +00003379 i = PyMapping_Size(env);
3380 if (i < 0)
3381 return NULL;
3382 envlist = PyMem_NEW(char *, i + 1);
3383 if (envlist == NULL) {
3384 PyErr_NoMemory();
3385 return NULL;
3386 }
3387 envc = 0;
3388 keys = PyMapping_Keys(env);
3389 vals = PyMapping_Values(env);
3390 if (!keys || !vals)
3391 goto error;
3392 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3393 PyErr_Format(PyExc_TypeError,
3394 "env.keys() or env.values() is not a list");
3395 goto error;
3396 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003397
Victor Stinner8c62be82010-05-06 00:08:46 +00003398 for (pos = 0; pos < i; pos++) {
3399 key = PyList_GetItem(keys, pos);
3400 val = PyList_GetItem(vals, pos);
3401 if (!key || !val)
3402 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003403
Victor Stinner8c62be82010-05-06 00:08:46 +00003404 if (PyUnicode_FSConverter(key, &key2) == 0)
3405 goto error;
3406 if (PyUnicode_FSConverter(val, &val2) == 0) {
3407 Py_DECREF(key2);
3408 goto error;
3409 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003410
3411#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3413 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003414#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003415 k = PyBytes_AsString(key2);
3416 v = PyBytes_AsString(val2);
3417 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003418
Victor Stinner8c62be82010-05-06 00:08:46 +00003419 p = PyMem_NEW(char, len);
3420 if (p == NULL) {
3421 PyErr_NoMemory();
3422 Py_DECREF(key2);
3423 Py_DECREF(val2);
3424 goto error;
3425 }
3426 PyOS_snprintf(p, len, "%s=%s", k, v);
3427 envlist[envc++] = p;
3428 Py_DECREF(key2);
3429 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003430#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003431 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003432#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003433 }
3434 Py_DECREF(vals);
3435 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003436
Victor Stinner8c62be82010-05-06 00:08:46 +00003437 envlist[envc] = 0;
3438 *envc_ptr = envc;
3439 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003440
3441error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003442 Py_XDECREF(keys);
3443 Py_XDECREF(vals);
3444 while (--envc >= 0)
3445 PyMem_DEL(envlist[envc]);
3446 PyMem_DEL(envlist);
3447 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003448}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003449
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003450PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003451"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003452Execute a path with arguments and environment, replacing current process.\n\
3453\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003454 path: path of executable file\n\
3455 args: tuple or list of arguments\n\
3456 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003457
Barry Warsaw53699e91996-12-10 23:23:01 +00003458static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003459posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003460{
Victor Stinner8c62be82010-05-06 00:08:46 +00003461 PyObject *opath;
3462 char *path;
3463 PyObject *argv, *env;
3464 char **argvlist;
3465 char **envlist;
3466 Py_ssize_t i, argc, envc;
3467 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3468 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003469
Victor Stinner8c62be82010-05-06 00:08:46 +00003470 /* execve has three arguments: (path, argv, env), where
3471 argv is a list or tuple of strings and env is a dictionary
3472 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003473
Victor Stinner8c62be82010-05-06 00:08:46 +00003474 if (!PyArg_ParseTuple(args, "O&OO:execve",
3475 PyUnicode_FSConverter,
3476 &opath, &argv, &env))
3477 return NULL;
3478 path = PyBytes_AsString(opath);
3479 if (PyList_Check(argv)) {
3480 argc = PyList_Size(argv);
3481 getitem = PyList_GetItem;
3482 }
3483 else if (PyTuple_Check(argv)) {
3484 argc = PyTuple_Size(argv);
3485 getitem = PyTuple_GetItem;
3486 }
3487 else {
3488 PyErr_SetString(PyExc_TypeError,
3489 "execve() arg 2 must be a tuple or list");
3490 goto fail_0;
3491 }
3492 if (!PyMapping_Check(env)) {
3493 PyErr_SetString(PyExc_TypeError,
3494 "execve() arg 3 must be a mapping object");
3495 goto fail_0;
3496 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003497
Victor Stinner8c62be82010-05-06 00:08:46 +00003498 argvlist = PyMem_NEW(char *, argc+1);
3499 if (argvlist == NULL) {
3500 PyErr_NoMemory();
3501 goto fail_0;
3502 }
3503 for (i = 0; i < argc; i++) {
3504 if (!fsconvert_strdup((*getitem)(argv, i),
3505 &argvlist[i]))
3506 {
3507 lastarg = i;
3508 goto fail_1;
3509 }
3510 }
3511 lastarg = argc;
3512 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003513
Victor Stinner8c62be82010-05-06 00:08:46 +00003514 envlist = parse_envlist(env, &envc);
3515 if (envlist == NULL)
3516 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003517
Victor Stinner8c62be82010-05-06 00:08:46 +00003518 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003519
Victor Stinner8c62be82010-05-06 00:08:46 +00003520 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003521
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003523
Victor Stinner8c62be82010-05-06 00:08:46 +00003524 while (--envc >= 0)
3525 PyMem_DEL(envlist[envc]);
3526 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003527 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003528 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003529 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003530 Py_DECREF(opath);
3531 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003532}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003533#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003534
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003535
Guido van Rossuma1065681999-01-25 23:20:23 +00003536#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003537PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003538"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003539Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003540\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003541 mode: mode of process creation\n\
3542 path: path of executable file\n\
3543 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003544
3545static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003546posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003547{
Victor Stinner8c62be82010-05-06 00:08:46 +00003548 PyObject *opath;
3549 char *path;
3550 PyObject *argv;
3551 char **argvlist;
3552 int mode, i;
3553 Py_ssize_t argc;
3554 Py_intptr_t spawnval;
3555 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003556
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 /* spawnv has three arguments: (mode, path, argv), where
3558 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003559
Victor Stinner8c62be82010-05-06 00:08:46 +00003560 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3561 PyUnicode_FSConverter,
3562 &opath, &argv))
3563 return NULL;
3564 path = PyBytes_AsString(opath);
3565 if (PyList_Check(argv)) {
3566 argc = PyList_Size(argv);
3567 getitem = PyList_GetItem;
3568 }
3569 else if (PyTuple_Check(argv)) {
3570 argc = PyTuple_Size(argv);
3571 getitem = PyTuple_GetItem;
3572 }
3573 else {
3574 PyErr_SetString(PyExc_TypeError,
3575 "spawnv() arg 2 must be a tuple or list");
3576 Py_DECREF(opath);
3577 return NULL;
3578 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003579
Victor Stinner8c62be82010-05-06 00:08:46 +00003580 argvlist = PyMem_NEW(char *, argc+1);
3581 if (argvlist == NULL) {
3582 Py_DECREF(opath);
3583 return PyErr_NoMemory();
3584 }
3585 for (i = 0; i < argc; i++) {
3586 if (!fsconvert_strdup((*getitem)(argv, i),
3587 &argvlist[i])) {
3588 free_string_array(argvlist, i);
3589 PyErr_SetString(
3590 PyExc_TypeError,
3591 "spawnv() arg 2 must contain only strings");
3592 Py_DECREF(opath);
3593 return NULL;
3594 }
3595 }
3596 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003597
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003598#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003599 Py_BEGIN_ALLOW_THREADS
3600 spawnval = spawnv(mode, path, argvlist);
3601 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003602#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003603 if (mode == _OLD_P_OVERLAY)
3604 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003605
Victor Stinner8c62be82010-05-06 00:08:46 +00003606 Py_BEGIN_ALLOW_THREADS
3607 spawnval = _spawnv(mode, path, argvlist);
3608 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003609#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003610
Victor Stinner8c62be82010-05-06 00:08:46 +00003611 free_string_array(argvlist, argc);
3612 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003613
Victor Stinner8c62be82010-05-06 00:08:46 +00003614 if (spawnval == -1)
3615 return posix_error();
3616 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003617#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003618 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003619#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003620 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003621#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003622}
3623
3624
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003625PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003626"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003627Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003628\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003629 mode: mode of process creation\n\
3630 path: path of executable file\n\
3631 args: tuple or list of arguments\n\
3632 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003633
3634static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003635posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003636{
Victor Stinner8c62be82010-05-06 00:08:46 +00003637 PyObject *opath;
3638 char *path;
3639 PyObject *argv, *env;
3640 char **argvlist;
3641 char **envlist;
3642 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003643 int mode;
3644 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003645 Py_intptr_t spawnval;
3646 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3647 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003648
Victor Stinner8c62be82010-05-06 00:08:46 +00003649 /* spawnve has four arguments: (mode, path, argv, env), where
3650 argv is a list or tuple of strings and env is a dictionary
3651 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003652
Victor Stinner8c62be82010-05-06 00:08:46 +00003653 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3654 PyUnicode_FSConverter,
3655 &opath, &argv, &env))
3656 return NULL;
3657 path = PyBytes_AsString(opath);
3658 if (PyList_Check(argv)) {
3659 argc = PyList_Size(argv);
3660 getitem = PyList_GetItem;
3661 }
3662 else if (PyTuple_Check(argv)) {
3663 argc = PyTuple_Size(argv);
3664 getitem = PyTuple_GetItem;
3665 }
3666 else {
3667 PyErr_SetString(PyExc_TypeError,
3668 "spawnve() arg 2 must be a tuple or list");
3669 goto fail_0;
3670 }
3671 if (!PyMapping_Check(env)) {
3672 PyErr_SetString(PyExc_TypeError,
3673 "spawnve() arg 3 must be a mapping object");
3674 goto fail_0;
3675 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003676
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 argvlist = PyMem_NEW(char *, argc+1);
3678 if (argvlist == NULL) {
3679 PyErr_NoMemory();
3680 goto fail_0;
3681 }
3682 for (i = 0; i < argc; i++) {
3683 if (!fsconvert_strdup((*getitem)(argv, i),
3684 &argvlist[i]))
3685 {
3686 lastarg = i;
3687 goto fail_1;
3688 }
3689 }
3690 lastarg = argc;
3691 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003692
Victor Stinner8c62be82010-05-06 00:08:46 +00003693 envlist = parse_envlist(env, &envc);
3694 if (envlist == NULL)
3695 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003696
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003697#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003698 Py_BEGIN_ALLOW_THREADS
3699 spawnval = spawnve(mode, path, argvlist, envlist);
3700 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003701#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003702 if (mode == _OLD_P_OVERLAY)
3703 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003704
Victor Stinner8c62be82010-05-06 00:08:46 +00003705 Py_BEGIN_ALLOW_THREADS
3706 spawnval = _spawnve(mode, path, argvlist, envlist);
3707 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003708#endif
Tim Peters25059d32001-12-07 20:35:43 +00003709
Victor Stinner8c62be82010-05-06 00:08:46 +00003710 if (spawnval == -1)
3711 (void) posix_error();
3712 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003713#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003714 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003715#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003716 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003717#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003718
Victor Stinner8c62be82010-05-06 00:08:46 +00003719 while (--envc >= 0)
3720 PyMem_DEL(envlist[envc]);
3721 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003722 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003723 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003724 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003725 Py_DECREF(opath);
3726 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003727}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003728
3729/* OS/2 supports spawnvp & spawnvpe natively */
3730#if defined(PYOS_OS2)
3731PyDoc_STRVAR(posix_spawnvp__doc__,
3732"spawnvp(mode, file, args)\n\n\
3733Execute the program 'file' in a new process, using the environment\n\
3734search path to find the file.\n\
3735\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003736 mode: mode of process creation\n\
3737 file: executable file name\n\
3738 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003739
3740static PyObject *
3741posix_spawnvp(PyObject *self, PyObject *args)
3742{
Victor Stinner8c62be82010-05-06 00:08:46 +00003743 PyObject *opath;
3744 char *path;
3745 PyObject *argv;
3746 char **argvlist;
3747 int mode, i, argc;
3748 Py_intptr_t spawnval;
3749 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003750
Victor Stinner8c62be82010-05-06 00:08:46 +00003751 /* spawnvp has three arguments: (mode, path, argv), where
3752 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003753
Victor Stinner8c62be82010-05-06 00:08:46 +00003754 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3755 PyUnicode_FSConverter,
3756 &opath, &argv))
3757 return NULL;
3758 path = PyBytes_AsString(opath);
3759 if (PyList_Check(argv)) {
3760 argc = PyList_Size(argv);
3761 getitem = PyList_GetItem;
3762 }
3763 else if (PyTuple_Check(argv)) {
3764 argc = PyTuple_Size(argv);
3765 getitem = PyTuple_GetItem;
3766 }
3767 else {
3768 PyErr_SetString(PyExc_TypeError,
3769 "spawnvp() arg 2 must be a tuple or list");
3770 Py_DECREF(opath);
3771 return NULL;
3772 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003773
Victor Stinner8c62be82010-05-06 00:08:46 +00003774 argvlist = PyMem_NEW(char *, argc+1);
3775 if (argvlist == NULL) {
3776 Py_DECREF(opath);
3777 return PyErr_NoMemory();
3778 }
3779 for (i = 0; i < argc; i++) {
3780 if (!fsconvert_strdup((*getitem)(argv, i),
3781 &argvlist[i])) {
3782 free_string_array(argvlist, i);
3783 PyErr_SetString(
3784 PyExc_TypeError,
3785 "spawnvp() arg 2 must contain only strings");
3786 Py_DECREF(opath);
3787 return NULL;
3788 }
3789 }
3790 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003791
Victor Stinner8c62be82010-05-06 00:08:46 +00003792 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003793#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003794 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003795#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003796 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003797#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003798 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003799
Victor Stinner8c62be82010-05-06 00:08:46 +00003800 free_string_array(argvlist, argc);
3801 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003802
Victor Stinner8c62be82010-05-06 00:08:46 +00003803 if (spawnval == -1)
3804 return posix_error();
3805 else
3806 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003807}
3808
3809
3810PyDoc_STRVAR(posix_spawnvpe__doc__,
3811"spawnvpe(mode, file, args, env)\n\n\
3812Execute the program 'file' in a new process, using the environment\n\
3813search path to find the file.\n\
3814\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003815 mode: mode of process creation\n\
3816 file: executable file name\n\
3817 args: tuple or list of arguments\n\
3818 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003819
3820static PyObject *
3821posix_spawnvpe(PyObject *self, PyObject *args)
3822{
Victor Stinner8c62be82010-05-06 00:08:46 +00003823 PyObject *opath
3824 char *path;
3825 PyObject *argv, *env;
3826 char **argvlist;
3827 char **envlist;
3828 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003829 int mode;
3830 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003831 Py_intptr_t spawnval;
3832 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3833 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003834
Victor Stinner8c62be82010-05-06 00:08:46 +00003835 /* spawnvpe has four arguments: (mode, path, argv, env), where
3836 argv is a list or tuple of strings and env is a dictionary
3837 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003838
Victor Stinner8c62be82010-05-06 00:08:46 +00003839 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3840 PyUnicode_FSConverter,
3841 &opath, &argv, &env))
3842 return NULL;
3843 path = PyBytes_AsString(opath);
3844 if (PyList_Check(argv)) {
3845 argc = PyList_Size(argv);
3846 getitem = PyList_GetItem;
3847 }
3848 else if (PyTuple_Check(argv)) {
3849 argc = PyTuple_Size(argv);
3850 getitem = PyTuple_GetItem;
3851 }
3852 else {
3853 PyErr_SetString(PyExc_TypeError,
3854 "spawnvpe() arg 2 must be a tuple or list");
3855 goto fail_0;
3856 }
3857 if (!PyMapping_Check(env)) {
3858 PyErr_SetString(PyExc_TypeError,
3859 "spawnvpe() arg 3 must be a mapping object");
3860 goto fail_0;
3861 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003862
Victor Stinner8c62be82010-05-06 00:08:46 +00003863 argvlist = PyMem_NEW(char *, argc+1);
3864 if (argvlist == NULL) {
3865 PyErr_NoMemory();
3866 goto fail_0;
3867 }
3868 for (i = 0; i < argc; i++) {
3869 if (!fsconvert_strdup((*getitem)(argv, i),
3870 &argvlist[i]))
3871 {
3872 lastarg = i;
3873 goto fail_1;
3874 }
3875 }
3876 lastarg = argc;
3877 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003878
Victor Stinner8c62be82010-05-06 00:08:46 +00003879 envlist = parse_envlist(env, &envc);
3880 if (envlist == NULL)
3881 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003882
Victor Stinner8c62be82010-05-06 00:08:46 +00003883 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003884#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003885 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003886#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003887 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003888#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003889 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003890
Victor Stinner8c62be82010-05-06 00:08:46 +00003891 if (spawnval == -1)
3892 (void) posix_error();
3893 else
3894 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003895
Victor Stinner8c62be82010-05-06 00:08:46 +00003896 while (--envc >= 0)
3897 PyMem_DEL(envlist[envc]);
3898 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003899 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003900 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003901 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003902 Py_DECREF(opath);
3903 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003904}
3905#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003906#endif /* HAVE_SPAWNV */
3907
3908
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003909#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003910PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003911"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003912Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3913\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003914Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003915
3916static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003917posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003918{
Victor Stinner8c62be82010-05-06 00:08:46 +00003919 pid_t pid;
3920 int result = 0;
3921 _PyImport_AcquireLock();
3922 pid = fork1();
3923 if (pid == 0) {
3924 /* child: this clobbers and resets the import lock. */
3925 PyOS_AfterFork();
3926 } else {
3927 /* parent: release the import lock. */
3928 result = _PyImport_ReleaseLock();
3929 }
3930 if (pid == -1)
3931 return posix_error();
3932 if (result < 0) {
3933 /* Don't clobber the OSError if the fork failed. */
3934 PyErr_SetString(PyExc_RuntimeError,
3935 "not holding the import lock");
3936 return NULL;
3937 }
3938 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003939}
3940#endif
3941
3942
Guido van Rossumad0ee831995-03-01 10:34:45 +00003943#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003944PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003945"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003946Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003947Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003948
Barry Warsaw53699e91996-12-10 23:23:01 +00003949static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003950posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003951{
Victor Stinner8c62be82010-05-06 00:08:46 +00003952 pid_t pid;
3953 int result = 0;
3954 _PyImport_AcquireLock();
3955 pid = fork();
3956 if (pid == 0) {
3957 /* child: this clobbers and resets the import lock. */
3958 PyOS_AfterFork();
3959 } else {
3960 /* parent: release the import lock. */
3961 result = _PyImport_ReleaseLock();
3962 }
3963 if (pid == -1)
3964 return posix_error();
3965 if (result < 0) {
3966 /* Don't clobber the OSError if the fork failed. */
3967 PyErr_SetString(PyExc_RuntimeError,
3968 "not holding the import lock");
3969 return NULL;
3970 }
3971 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003972}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003973#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003974
Neal Norwitzb59798b2003-03-21 01:43:31 +00003975/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003976/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3977#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003978#define DEV_PTY_FILE "/dev/ptc"
3979#define HAVE_DEV_PTMX
3980#else
3981#define DEV_PTY_FILE "/dev/ptmx"
3982#endif
3983
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003984#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003985#ifdef HAVE_PTY_H
3986#include <pty.h>
3987#else
3988#ifdef HAVE_LIBUTIL_H
3989#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00003990#else
3991#ifdef HAVE_UTIL_H
3992#include <util.h>
3993#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003994#endif /* HAVE_LIBUTIL_H */
3995#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003996#ifdef HAVE_STROPTS_H
3997#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003998#endif
3999#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004000
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004001#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004002PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004003"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004004Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004005
4006static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004007posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004008{
Victor Stinner8c62be82010-05-06 00:08:46 +00004009 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004010#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004011 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004012#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004013#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004014 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004015#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00004016 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004017#endif
4018#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004019
Thomas Wouters70c21a12000-07-14 14:28:33 +00004020#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004021 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4022 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004023#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004024 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4025 if (slave_name == NULL)
4026 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004027
Victor Stinner8c62be82010-05-06 00:08:46 +00004028 slave_fd = open(slave_name, O_RDWR);
4029 if (slave_fd < 0)
4030 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004031#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004032 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4033 if (master_fd < 0)
4034 return posix_error();
4035 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4036 /* change permission of slave */
4037 if (grantpt(master_fd) < 0) {
4038 PyOS_setsig(SIGCHLD, sig_saved);
4039 return posix_error();
4040 }
4041 /* unlock slave */
4042 if (unlockpt(master_fd) < 0) {
4043 PyOS_setsig(SIGCHLD, sig_saved);
4044 return posix_error();
4045 }
4046 PyOS_setsig(SIGCHLD, sig_saved);
4047 slave_name = ptsname(master_fd); /* get name of slave */
4048 if (slave_name == NULL)
4049 return posix_error();
4050 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4051 if (slave_fd < 0)
4052 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004053#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004054 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4055 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004056#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004057 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004058#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004059#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004060#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004061
Victor Stinner8c62be82010-05-06 00:08:46 +00004062 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004063
Fred Drake8cef4cf2000-06-28 16:40:38 +00004064}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004065#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004066
4067#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004068PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004069"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004070Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4071Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004072To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004073
4074static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004075posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004076{
Victor Stinner8c62be82010-05-06 00:08:46 +00004077 int master_fd = -1, result = 0;
4078 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004079
Victor Stinner8c62be82010-05-06 00:08:46 +00004080 _PyImport_AcquireLock();
4081 pid = forkpty(&master_fd, NULL, NULL, NULL);
4082 if (pid == 0) {
4083 /* child: this clobbers and resets the import lock. */
4084 PyOS_AfterFork();
4085 } else {
4086 /* parent: release the import lock. */
4087 result = _PyImport_ReleaseLock();
4088 }
4089 if (pid == -1)
4090 return posix_error();
4091 if (result < 0) {
4092 /* Don't clobber the OSError if the fork failed. */
4093 PyErr_SetString(PyExc_RuntimeError,
4094 "not holding the import lock");
4095 return NULL;
4096 }
4097 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004098}
4099#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004100
Guido van Rossumad0ee831995-03-01 10:34:45 +00004101#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004102PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004103"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004104Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004105
Barry Warsaw53699e91996-12-10 23:23:01 +00004106static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004107posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004108{
Victor Stinner8c62be82010-05-06 00:08:46 +00004109 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004110}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004111#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004112
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004113
Guido van Rossumad0ee831995-03-01 10:34:45 +00004114#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004115PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004116"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004117Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004118
Barry Warsaw53699e91996-12-10 23:23:01 +00004119static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004120posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004121{
Victor Stinner8c62be82010-05-06 00:08:46 +00004122 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004123}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004124#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004125
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004126
Guido van Rossumad0ee831995-03-01 10:34:45 +00004127#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004128PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004129"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004130Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004131
Barry Warsaw53699e91996-12-10 23:23:01 +00004132static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004133posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004134{
Victor Stinner8c62be82010-05-06 00:08:46 +00004135 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004136}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004137#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004138
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004139
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004140PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004141"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004142Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004143
Barry Warsaw53699e91996-12-10 23:23:01 +00004144static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004145posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004146{
Victor Stinner8c62be82010-05-06 00:08:46 +00004147 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004148}
4149
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004150
Fred Drakec9680921999-12-13 16:37:25 +00004151#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004152PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004153"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004154Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004155
4156static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004157posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004158{
4159 PyObject *result = NULL;
4160
Fred Drakec9680921999-12-13 16:37:25 +00004161#ifdef NGROUPS_MAX
4162#define MAX_GROUPS NGROUPS_MAX
4163#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004164 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004165#define MAX_GROUPS 64
4166#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004167 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004168
4169 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
4170 * This is a helper variable to store the intermediate result when
4171 * that happens.
4172 *
4173 * To keep the code readable the OSX behaviour is unconditional,
4174 * according to the POSIX spec this should be safe on all unix-y
4175 * systems.
4176 */
4177 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00004178 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004179
Victor Stinner8c62be82010-05-06 00:08:46 +00004180 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004181 if (n < 0) {
4182 if (errno == EINVAL) {
4183 n = getgroups(0, NULL);
4184 if (n == -1) {
4185 return posix_error();
4186 }
4187 if (n == 0) {
4188 /* Avoid malloc(0) */
4189 alt_grouplist = grouplist;
4190 } else {
4191 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4192 if (alt_grouplist == NULL) {
4193 errno = EINVAL;
4194 return posix_error();
4195 }
4196 n = getgroups(n, alt_grouplist);
4197 if (n == -1) {
4198 PyMem_Free(alt_grouplist);
4199 return posix_error();
4200 }
4201 }
4202 } else {
4203 return posix_error();
4204 }
4205 }
4206 result = PyList_New(n);
4207 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004208 int i;
4209 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004210 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00004211 if (o == NULL) {
4212 Py_DECREF(result);
4213 result = NULL;
4214 break;
Fred Drakec9680921999-12-13 16:37:25 +00004215 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004216 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004217 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004218 }
4219
4220 if (alt_grouplist != grouplist) {
4221 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00004222 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004223
Fred Drakec9680921999-12-13 16:37:25 +00004224 return result;
4225}
4226#endif
4227
Antoine Pitroub7572f02009-12-02 20:46:48 +00004228#ifdef HAVE_INITGROUPS
4229PyDoc_STRVAR(posix_initgroups__doc__,
4230"initgroups(username, gid) -> None\n\n\
4231Call the system initgroups() to initialize the group access list with all of\n\
4232the groups of which the specified username is a member, plus the specified\n\
4233group id.");
4234
4235static PyObject *
4236posix_initgroups(PyObject *self, PyObject *args)
4237{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004238 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00004239 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004240 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004241 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004242
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004243 if (!PyArg_ParseTuple(args, "O&l:initgroups",
4244 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00004245 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004246 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004247
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004248 res = initgroups(username, (gid_t) gid);
4249 Py_DECREF(oname);
4250 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00004251 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004252
Victor Stinner8c62be82010-05-06 00:08:46 +00004253 Py_INCREF(Py_None);
4254 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004255}
4256#endif
4257
Martin v. Löwis606edc12002-06-13 21:09:11 +00004258#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004259PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004260"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004261Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004262
4263static PyObject *
4264posix_getpgid(PyObject *self, PyObject *args)
4265{
Victor Stinner8c62be82010-05-06 00:08:46 +00004266 pid_t pid, pgid;
4267 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4268 return NULL;
4269 pgid = getpgid(pid);
4270 if (pgid < 0)
4271 return posix_error();
4272 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004273}
4274#endif /* HAVE_GETPGID */
4275
4276
Guido van Rossumb6775db1994-08-01 11:34:53 +00004277#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004278PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004279"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004280Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004281
Barry Warsaw53699e91996-12-10 23:23:01 +00004282static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004283posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004284{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004285#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004286 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004287#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004288 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004289#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004290}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004291#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004292
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004293
Guido van Rossumb6775db1994-08-01 11:34:53 +00004294#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004295PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004296"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004297Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004298
Barry Warsaw53699e91996-12-10 23:23:01 +00004299static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004300posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004301{
Guido van Rossum64933891994-10-20 21:56:42 +00004302#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004303 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004304#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004305 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004306#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004307 return posix_error();
4308 Py_INCREF(Py_None);
4309 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004310}
4311
Guido van Rossumb6775db1994-08-01 11:34:53 +00004312#endif /* HAVE_SETPGRP */
4313
Guido van Rossumad0ee831995-03-01 10:34:45 +00004314#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004315
4316#ifdef MS_WINDOWS
4317#include <tlhelp32.h>
4318
4319static PyObject*
4320win32_getppid()
4321{
4322 HANDLE snapshot;
4323 pid_t mypid;
4324 PyObject* result = NULL;
4325 BOOL have_record;
4326 PROCESSENTRY32 pe;
4327
4328 mypid = getpid(); /* This function never fails */
4329
4330 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
4331 if (snapshot == INVALID_HANDLE_VALUE)
4332 return PyErr_SetFromWindowsErr(GetLastError());
4333
4334 pe.dwSize = sizeof(pe);
4335 have_record = Process32First(snapshot, &pe);
4336 while (have_record) {
4337 if (mypid == (pid_t)pe.th32ProcessID) {
4338 /* We could cache the ulong value in a static variable. */
4339 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
4340 break;
4341 }
4342
4343 have_record = Process32Next(snapshot, &pe);
4344 }
4345
4346 /* If our loop exits and our pid was not found (result will be NULL)
4347 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
4348 * error anyway, so let's raise it. */
4349 if (!result)
4350 result = PyErr_SetFromWindowsErr(GetLastError());
4351
4352 CloseHandle(snapshot);
4353
4354 return result;
4355}
4356#endif /*MS_WINDOWS*/
4357
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004358PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004359"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004360Return the parent's process id. If the parent process has already exited,\n\
4361Windows machines will still return its id; others systems will return the id\n\
4362of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004363
Barry Warsaw53699e91996-12-10 23:23:01 +00004364static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004365posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004366{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004367#ifdef MS_WINDOWS
4368 return win32_getppid();
4369#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004370 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00004371#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004372}
4373#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004374
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004375
Fred Drake12c6e2d1999-12-14 21:25:03 +00004376#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004377PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004378"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004379Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004380
4381static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004382posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004383{
Victor Stinner8c62be82010-05-06 00:08:46 +00004384 PyObject *result = NULL;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004385#ifdef MS_WINDOWS
4386 wchar_t user_name[UNLEN + 1];
4387 DWORD num_chars = sizeof(user_name)/sizeof(user_name[0]);
4388
4389 if (GetUserNameW(user_name, &num_chars)) {
4390 /* num_chars is the number of unicode chars plus null terminator */
4391 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
4392 }
4393 else
4394 result = PyErr_SetFromWindowsErr(GetLastError());
4395#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004396 char *name;
4397 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004398
Victor Stinner8c62be82010-05-06 00:08:46 +00004399 errno = 0;
4400 name = getlogin();
4401 if (name == NULL) {
4402 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00004403 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004404 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004405 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00004406 }
4407 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004408 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00004409 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004410#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00004411 return result;
4412}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00004413#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00004414
Guido van Rossumad0ee831995-03-01 10:34:45 +00004415#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004416PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004417"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004418Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004419
Barry Warsaw53699e91996-12-10 23:23:01 +00004420static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004421posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004422{
Victor Stinner8c62be82010-05-06 00:08:46 +00004423 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004424}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004425#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004426
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004427
Guido van Rossumad0ee831995-03-01 10:34:45 +00004428#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004429PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004430"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004431Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004432
Barry Warsaw53699e91996-12-10 23:23:01 +00004433static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004434posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004435{
Victor Stinner8c62be82010-05-06 00:08:46 +00004436 pid_t pid;
4437 int sig;
4438 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4439 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004440#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004441 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4442 APIRET rc;
4443 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004444 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004445
4446 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4447 APIRET rc;
4448 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004449 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004450
4451 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004452 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004453#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004454 if (kill(pid, sig) == -1)
4455 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004456#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004457 Py_INCREF(Py_None);
4458 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004459}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004460#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004461
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004462#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004463PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004464"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004465Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004466
4467static PyObject *
4468posix_killpg(PyObject *self, PyObject *args)
4469{
Victor Stinner8c62be82010-05-06 00:08:46 +00004470 int sig;
4471 pid_t pgid;
4472 /* XXX some man pages make the `pgid` parameter an int, others
4473 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4474 take the same type. Moreover, pid_t is always at least as wide as
4475 int (else compilation of this module fails), which is safe. */
4476 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4477 return NULL;
4478 if (killpg(pgid, sig) == -1)
4479 return posix_error();
4480 Py_INCREF(Py_None);
4481 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004482}
4483#endif
4484
Brian Curtineb24d742010-04-12 17:16:38 +00004485#ifdef MS_WINDOWS
4486PyDoc_STRVAR(win32_kill__doc__,
4487"kill(pid, sig)\n\n\
4488Kill a process with a signal.");
4489
4490static PyObject *
4491win32_kill(PyObject *self, PyObject *args)
4492{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004493 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004494 DWORD pid, sig, err;
4495 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004496
Victor Stinner8c62be82010-05-06 00:08:46 +00004497 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4498 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004499
Victor Stinner8c62be82010-05-06 00:08:46 +00004500 /* Console processes which share a common console can be sent CTRL+C or
4501 CTRL+BREAK events, provided they handle said events. */
4502 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4503 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4504 err = GetLastError();
4505 PyErr_SetFromWindowsErr(err);
4506 }
4507 else
4508 Py_RETURN_NONE;
4509 }
Brian Curtineb24d742010-04-12 17:16:38 +00004510
Victor Stinner8c62be82010-05-06 00:08:46 +00004511 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4512 attempt to open and terminate the process. */
4513 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4514 if (handle == NULL) {
4515 err = GetLastError();
4516 return PyErr_SetFromWindowsErr(err);
4517 }
Brian Curtineb24d742010-04-12 17:16:38 +00004518
Victor Stinner8c62be82010-05-06 00:08:46 +00004519 if (TerminateProcess(handle, sig) == 0) {
4520 err = GetLastError();
4521 result = PyErr_SetFromWindowsErr(err);
4522 } else {
4523 Py_INCREF(Py_None);
4524 result = Py_None;
4525 }
Brian Curtineb24d742010-04-12 17:16:38 +00004526
Victor Stinner8c62be82010-05-06 00:08:46 +00004527 CloseHandle(handle);
4528 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004529}
4530#endif /* MS_WINDOWS */
4531
Guido van Rossumc0125471996-06-28 18:55:32 +00004532#ifdef HAVE_PLOCK
4533
4534#ifdef HAVE_SYS_LOCK_H
4535#include <sys/lock.h>
4536#endif
4537
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004538PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004539"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004540Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004541
Barry Warsaw53699e91996-12-10 23:23:01 +00004542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004543posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004544{
Victor Stinner8c62be82010-05-06 00:08:46 +00004545 int op;
4546 if (!PyArg_ParseTuple(args, "i:plock", &op))
4547 return NULL;
4548 if (plock(op) == -1)
4549 return posix_error();
4550 Py_INCREF(Py_None);
4551 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004552}
4553#endif
4554
Guido van Rossumb6775db1994-08-01 11:34:53 +00004555#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004556PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004557"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004558Set the current process's user id.");
4559
Barry Warsaw53699e91996-12-10 23:23:01 +00004560static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004561posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004562{
Victor Stinner8c62be82010-05-06 00:08:46 +00004563 long uid_arg;
4564 uid_t uid;
4565 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4566 return NULL;
4567 uid = uid_arg;
4568 if (uid != uid_arg) {
4569 PyErr_SetString(PyExc_OverflowError, "user id too big");
4570 return NULL;
4571 }
4572 if (setuid(uid) < 0)
4573 return posix_error();
4574 Py_INCREF(Py_None);
4575 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004576}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004577#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004578
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004579
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004580#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004581PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004582"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004583Set the current process's effective user id.");
4584
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004585static PyObject *
4586posix_seteuid (PyObject *self, PyObject *args)
4587{
Victor Stinner8c62be82010-05-06 00:08:46 +00004588 long euid_arg;
4589 uid_t euid;
4590 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4591 return NULL;
4592 euid = euid_arg;
4593 if (euid != euid_arg) {
4594 PyErr_SetString(PyExc_OverflowError, "user id too big");
4595 return NULL;
4596 }
4597 if (seteuid(euid) < 0) {
4598 return posix_error();
4599 } else {
4600 Py_INCREF(Py_None);
4601 return Py_None;
4602 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004603}
4604#endif /* HAVE_SETEUID */
4605
4606#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004607PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004608"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004609Set the current process's effective group id.");
4610
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004611static PyObject *
4612posix_setegid (PyObject *self, PyObject *args)
4613{
Victor Stinner8c62be82010-05-06 00:08:46 +00004614 long egid_arg;
4615 gid_t egid;
4616 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4617 return NULL;
4618 egid = egid_arg;
4619 if (egid != egid_arg) {
4620 PyErr_SetString(PyExc_OverflowError, "group id too big");
4621 return NULL;
4622 }
4623 if (setegid(egid) < 0) {
4624 return posix_error();
4625 } else {
4626 Py_INCREF(Py_None);
4627 return Py_None;
4628 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004629}
4630#endif /* HAVE_SETEGID */
4631
4632#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004633PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004634"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004635Set the current process's real and effective user ids.");
4636
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004637static PyObject *
4638posix_setreuid (PyObject *self, PyObject *args)
4639{
Victor Stinner8c62be82010-05-06 00:08:46 +00004640 long ruid_arg, euid_arg;
4641 uid_t ruid, euid;
4642 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4643 return NULL;
4644 if (ruid_arg == -1)
4645 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4646 else
4647 ruid = ruid_arg; /* otherwise, assign from our long */
4648 if (euid_arg == -1)
4649 euid = (uid_t)-1;
4650 else
4651 euid = euid_arg;
4652 if ((euid_arg != -1 && euid != euid_arg) ||
4653 (ruid_arg != -1 && ruid != ruid_arg)) {
4654 PyErr_SetString(PyExc_OverflowError, "user id too big");
4655 return NULL;
4656 }
4657 if (setreuid(ruid, euid) < 0) {
4658 return posix_error();
4659 } else {
4660 Py_INCREF(Py_None);
4661 return Py_None;
4662 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004663}
4664#endif /* HAVE_SETREUID */
4665
4666#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004667PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004668"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004669Set the current process's real and effective group ids.");
4670
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004671static PyObject *
4672posix_setregid (PyObject *self, PyObject *args)
4673{
Victor Stinner8c62be82010-05-06 00:08:46 +00004674 long rgid_arg, egid_arg;
4675 gid_t rgid, egid;
4676 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4677 return NULL;
4678 if (rgid_arg == -1)
4679 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4680 else
4681 rgid = rgid_arg; /* otherwise, assign from our long */
4682 if (egid_arg == -1)
4683 egid = (gid_t)-1;
4684 else
4685 egid = egid_arg;
4686 if ((egid_arg != -1 && egid != egid_arg) ||
4687 (rgid_arg != -1 && rgid != rgid_arg)) {
4688 PyErr_SetString(PyExc_OverflowError, "group id too big");
4689 return NULL;
4690 }
4691 if (setregid(rgid, egid) < 0) {
4692 return posix_error();
4693 } else {
4694 Py_INCREF(Py_None);
4695 return Py_None;
4696 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004697}
4698#endif /* HAVE_SETREGID */
4699
Guido van Rossumb6775db1994-08-01 11:34:53 +00004700#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004701PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004702"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004703Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004704
Barry Warsaw53699e91996-12-10 23:23:01 +00004705static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004706posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004707{
Victor Stinner8c62be82010-05-06 00:08:46 +00004708 long gid_arg;
4709 gid_t gid;
4710 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4711 return NULL;
4712 gid = gid_arg;
4713 if (gid != gid_arg) {
4714 PyErr_SetString(PyExc_OverflowError, "group id too big");
4715 return NULL;
4716 }
4717 if (setgid(gid) < 0)
4718 return posix_error();
4719 Py_INCREF(Py_None);
4720 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004721}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004722#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004723
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004724#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004725PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004726"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004727Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004728
4729static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004730posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004731{
Victor Stinner8c62be82010-05-06 00:08:46 +00004732 int i, len;
4733 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004734
Victor Stinner8c62be82010-05-06 00:08:46 +00004735 if (!PySequence_Check(groups)) {
4736 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4737 return NULL;
4738 }
4739 len = PySequence_Size(groups);
4740 if (len > MAX_GROUPS) {
4741 PyErr_SetString(PyExc_ValueError, "too many groups");
4742 return NULL;
4743 }
4744 for(i = 0; i < len; i++) {
4745 PyObject *elem;
4746 elem = PySequence_GetItem(groups, i);
4747 if (!elem)
4748 return NULL;
4749 if (!PyLong_Check(elem)) {
4750 PyErr_SetString(PyExc_TypeError,
4751 "groups must be integers");
4752 Py_DECREF(elem);
4753 return NULL;
4754 } else {
4755 unsigned long x = PyLong_AsUnsignedLong(elem);
4756 if (PyErr_Occurred()) {
4757 PyErr_SetString(PyExc_TypeError,
4758 "group id too big");
4759 Py_DECREF(elem);
4760 return NULL;
4761 }
4762 grouplist[i] = x;
4763 /* read back the value to see if it fitted in gid_t */
4764 if (grouplist[i] != x) {
4765 PyErr_SetString(PyExc_TypeError,
4766 "group id too big");
4767 Py_DECREF(elem);
4768 return NULL;
4769 }
4770 }
4771 Py_DECREF(elem);
4772 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004773
Victor Stinner8c62be82010-05-06 00:08:46 +00004774 if (setgroups(len, grouplist) < 0)
4775 return posix_error();
4776 Py_INCREF(Py_None);
4777 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004778}
4779#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004780
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004781#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4782static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004783wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004784{
Victor Stinner8c62be82010-05-06 00:08:46 +00004785 PyObject *result;
4786 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004787
Victor Stinner8c62be82010-05-06 00:08:46 +00004788 if (pid == -1)
4789 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004790
Victor Stinner8c62be82010-05-06 00:08:46 +00004791 if (struct_rusage == NULL) {
4792 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4793 if (m == NULL)
4794 return NULL;
4795 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4796 Py_DECREF(m);
4797 if (struct_rusage == NULL)
4798 return NULL;
4799 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004800
Victor Stinner8c62be82010-05-06 00:08:46 +00004801 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4802 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4803 if (!result)
4804 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004805
4806#ifndef doubletime
4807#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4808#endif
4809
Victor Stinner8c62be82010-05-06 00:08:46 +00004810 PyStructSequence_SET_ITEM(result, 0,
4811 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4812 PyStructSequence_SET_ITEM(result, 1,
4813 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004814#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004815 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4816 SET_INT(result, 2, ru->ru_maxrss);
4817 SET_INT(result, 3, ru->ru_ixrss);
4818 SET_INT(result, 4, ru->ru_idrss);
4819 SET_INT(result, 5, ru->ru_isrss);
4820 SET_INT(result, 6, ru->ru_minflt);
4821 SET_INT(result, 7, ru->ru_majflt);
4822 SET_INT(result, 8, ru->ru_nswap);
4823 SET_INT(result, 9, ru->ru_inblock);
4824 SET_INT(result, 10, ru->ru_oublock);
4825 SET_INT(result, 11, ru->ru_msgsnd);
4826 SET_INT(result, 12, ru->ru_msgrcv);
4827 SET_INT(result, 13, ru->ru_nsignals);
4828 SET_INT(result, 14, ru->ru_nvcsw);
4829 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004830#undef SET_INT
4831
Victor Stinner8c62be82010-05-06 00:08:46 +00004832 if (PyErr_Occurred()) {
4833 Py_DECREF(result);
4834 return NULL;
4835 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004836
Victor Stinner8c62be82010-05-06 00:08:46 +00004837 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004838}
4839#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4840
4841#ifdef HAVE_WAIT3
4842PyDoc_STRVAR(posix_wait3__doc__,
4843"wait3(options) -> (pid, status, rusage)\n\n\
4844Wait for completion of a child process.");
4845
4846static PyObject *
4847posix_wait3(PyObject *self, PyObject *args)
4848{
Victor Stinner8c62be82010-05-06 00:08:46 +00004849 pid_t pid;
4850 int options;
4851 struct rusage ru;
4852 WAIT_TYPE status;
4853 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004854
Victor Stinner8c62be82010-05-06 00:08:46 +00004855 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4856 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004857
Victor Stinner8c62be82010-05-06 00:08:46 +00004858 Py_BEGIN_ALLOW_THREADS
4859 pid = wait3(&status, options, &ru);
4860 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004861
Victor Stinner8c62be82010-05-06 00:08:46 +00004862 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004863}
4864#endif /* HAVE_WAIT3 */
4865
4866#ifdef HAVE_WAIT4
4867PyDoc_STRVAR(posix_wait4__doc__,
4868"wait4(pid, options) -> (pid, status, rusage)\n\n\
4869Wait for completion of a given child process.");
4870
4871static PyObject *
4872posix_wait4(PyObject *self, PyObject *args)
4873{
Victor Stinner8c62be82010-05-06 00:08:46 +00004874 pid_t pid;
4875 int options;
4876 struct rusage ru;
4877 WAIT_TYPE status;
4878 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004879
Victor Stinner8c62be82010-05-06 00:08:46 +00004880 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
4881 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004882
Victor Stinner8c62be82010-05-06 00:08:46 +00004883 Py_BEGIN_ALLOW_THREADS
4884 pid = wait4(pid, &status, options, &ru);
4885 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004886
Victor Stinner8c62be82010-05-06 00:08:46 +00004887 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004888}
4889#endif /* HAVE_WAIT4 */
4890
Guido van Rossumb6775db1994-08-01 11:34:53 +00004891#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004892PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004893"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004894Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004895
Barry Warsaw53699e91996-12-10 23:23:01 +00004896static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004897posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004898{
Victor Stinner8c62be82010-05-06 00:08:46 +00004899 pid_t pid;
4900 int options;
4901 WAIT_TYPE status;
4902 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004903
Victor Stinner8c62be82010-05-06 00:08:46 +00004904 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4905 return NULL;
4906 Py_BEGIN_ALLOW_THREADS
4907 pid = waitpid(pid, &status, options);
4908 Py_END_ALLOW_THREADS
4909 if (pid == -1)
4910 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004911
Victor Stinner8c62be82010-05-06 00:08:46 +00004912 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004913}
4914
Tim Petersab034fa2002-02-01 11:27:43 +00004915#elif defined(HAVE_CWAIT)
4916
4917/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004918PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004919"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004920"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004921
4922static PyObject *
4923posix_waitpid(PyObject *self, PyObject *args)
4924{
Victor Stinner8c62be82010-05-06 00:08:46 +00004925 Py_intptr_t pid;
4926 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004927
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4929 return NULL;
4930 Py_BEGIN_ALLOW_THREADS
4931 pid = _cwait(&status, pid, options);
4932 Py_END_ALLOW_THREADS
4933 if (pid == -1)
4934 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004935
Victor Stinner8c62be82010-05-06 00:08:46 +00004936 /* shift the status left a byte so this is more like the POSIX waitpid */
4937 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004938}
4939#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004940
Guido van Rossumad0ee831995-03-01 10:34:45 +00004941#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004942PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004943"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004944Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004945
Barry Warsaw53699e91996-12-10 23:23:01 +00004946static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004947posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004948{
Victor Stinner8c62be82010-05-06 00:08:46 +00004949 pid_t pid;
4950 WAIT_TYPE status;
4951 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004952
Victor Stinner8c62be82010-05-06 00:08:46 +00004953 Py_BEGIN_ALLOW_THREADS
4954 pid = wait(&status);
4955 Py_END_ALLOW_THREADS
4956 if (pid == -1)
4957 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004958
Victor Stinner8c62be82010-05-06 00:08:46 +00004959 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00004960}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004961#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004962
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004963
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004964PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004965"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004966Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004967
Barry Warsaw53699e91996-12-10 23:23:01 +00004968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004969posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004970{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004971#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00004972 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004973#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004974#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00004975 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat",
4976 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004977#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004978 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004979#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004980#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004981}
4982
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004983
Guido van Rossumb6775db1994-08-01 11:34:53 +00004984#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004985PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004986"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004987Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004988
Barry Warsaw53699e91996-12-10 23:23:01 +00004989static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004990posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004991{
Victor Stinner8c62be82010-05-06 00:08:46 +00004992 PyObject* v;
4993 char buf[MAXPATHLEN];
4994 PyObject *opath;
4995 char *path;
4996 int n;
4997 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00004998
Victor Stinner8c62be82010-05-06 00:08:46 +00004999 if (!PyArg_ParseTuple(args, "O&:readlink",
5000 PyUnicode_FSConverter, &opath))
5001 return NULL;
5002 path = PyBytes_AsString(opath);
5003 v = PySequence_GetItem(args, 0);
5004 if (v == NULL) {
5005 Py_DECREF(opath);
5006 return NULL;
5007 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00005008
Victor Stinner8c62be82010-05-06 00:08:46 +00005009 if (PyUnicode_Check(v)) {
5010 arg_is_unicode = 1;
5011 }
5012 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005013
Victor Stinner8c62be82010-05-06 00:08:46 +00005014 Py_BEGIN_ALLOW_THREADS
5015 n = readlink(path, buf, (int) sizeof buf);
5016 Py_END_ALLOW_THREADS
5017 if (n < 0)
5018 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005019
Victor Stinner8c62be82010-05-06 00:08:46 +00005020 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00005021 if (arg_is_unicode)
5022 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
5023 else
5024 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005025}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005026#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005027
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005028
Guido van Rossumb6775db1994-08-01 11:34:53 +00005029#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005030PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005031"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005032Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005033
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005034static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005035posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005036{
Victor Stinner8c62be82010-05-06 00:08:46 +00005037 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005038}
5039#endif /* HAVE_SYMLINK */
5040
Brian Curtind40e6f72010-07-08 21:39:08 +00005041#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
5042
5043PyDoc_STRVAR(win_readlink__doc__,
5044"readlink(path) -> path\n\n\
5045Return a string representing the path to which the symbolic link points.");
5046
5047/* The following structure was copied from
5048 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
5049 include doesn't seem to be present in the Windows SDK (at least as included
5050 with Visual Studio Express). */
5051typedef struct _REPARSE_DATA_BUFFER {
5052 ULONG ReparseTag;
5053 USHORT ReparseDataLength;
5054 USHORT Reserved;
5055 union {
5056 struct {
5057 USHORT SubstituteNameOffset;
5058 USHORT SubstituteNameLength;
5059 USHORT PrintNameOffset;
5060 USHORT PrintNameLength;
5061 ULONG Flags;
5062 WCHAR PathBuffer[1];
5063 } SymbolicLinkReparseBuffer;
5064
5065 struct {
5066 USHORT SubstituteNameOffset;
5067 USHORT SubstituteNameLength;
5068 USHORT PrintNameOffset;
5069 USHORT PrintNameLength;
5070 WCHAR PathBuffer[1];
5071 } MountPointReparseBuffer;
5072
5073 struct {
5074 UCHAR DataBuffer[1];
5075 } GenericReparseBuffer;
5076 };
5077} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
5078
Brian Curtin74e45612010-07-09 15:58:59 +00005079#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
5080 GenericReparseBuffer)
Brian Curtind40e6f72010-07-08 21:39:08 +00005081
5082#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
5083
5084/* Windows readlink implementation */
5085static PyObject *
5086win_readlink(PyObject *self, PyObject *args)
5087{
5088 wchar_t *path;
5089 DWORD n_bytes_returned;
5090 DWORD io_result;
5091 PyObject *result;
5092 HANDLE reparse_point_handle;
5093
5094 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
5095 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
5096 wchar_t *print_name;
5097
5098 if (!PyArg_ParseTuple(args,
5099 "u:readlink",
5100 &path))
5101 return NULL;
5102
5103 /* First get a handle to the reparse point */
5104 Py_BEGIN_ALLOW_THREADS
5105 reparse_point_handle = CreateFileW(
5106 path,
5107 0,
5108 0,
5109 0,
5110 OPEN_EXISTING,
5111 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
5112 0);
5113 Py_END_ALLOW_THREADS
5114
5115 if (reparse_point_handle==INVALID_HANDLE_VALUE)
5116 {
5117 return win32_error_unicode("readlink", path);
5118 }
5119
5120 Py_BEGIN_ALLOW_THREADS
5121 /* New call DeviceIoControl to read the reparse point */
5122 io_result = DeviceIoControl(
5123 reparse_point_handle,
5124 FSCTL_GET_REPARSE_POINT,
5125 0, 0, /* in buffer */
5126 target_buffer, sizeof(target_buffer),
5127 &n_bytes_returned,
5128 0 /* we're not using OVERLAPPED_IO */
5129 );
5130 CloseHandle(reparse_point_handle);
5131 Py_END_ALLOW_THREADS
5132
5133 if (io_result==0)
5134 {
5135 return win32_error_unicode("readlink", path);
5136 }
5137
5138 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5139 {
5140 PyErr_SetString(PyExc_ValueError,
5141 "not a symbolic link");
5142 return NULL;
5143 }
Brian Curtin74e45612010-07-09 15:58:59 +00005144 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
5145 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5146
5147 result = PyUnicode_FromWideChar(print_name,
5148 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00005149 return result;
5150}
5151
5152#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5153
5154#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
5155
5156/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5157static int has_CreateSymbolicLinkW = 0;
5158static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5159static int
5160check_CreateSymbolicLinkW()
5161{
5162 HINSTANCE hKernel32;
5163 /* only recheck */
5164 if (has_CreateSymbolicLinkW)
5165 return has_CreateSymbolicLinkW;
5166 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00005167 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
5168 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00005169 if (Py_CreateSymbolicLinkW)
5170 has_CreateSymbolicLinkW = 1;
5171 return has_CreateSymbolicLinkW;
5172}
5173
5174PyDoc_STRVAR(win_symlink__doc__,
5175"symlink(src, dst, target_is_directory=False)\n\n\
5176Create a symbolic link pointing to src named dst.\n\
5177target_is_directory is required if the target is to be interpreted as\n\
5178a directory.\n\
5179This function requires Windows 6.0 or greater, and raises a\n\
5180NotImplementedError otherwise.");
5181
5182static PyObject *
5183win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5184{
5185 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5186 PyObject *src, *dest;
5187 int target_is_directory = 0;
5188 DWORD res;
5189 WIN32_FILE_ATTRIBUTE_DATA src_info;
5190
5191 if (!check_CreateSymbolicLinkW())
5192 {
5193 /* raise NotImplementedError */
5194 return PyErr_Format(PyExc_NotImplementedError,
5195 "CreateSymbolicLinkW not found");
5196 }
5197 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5198 kwlist, &src, &dest, &target_is_directory))
5199 return NULL;
5200 if (!convert_to_unicode(&src)) { return NULL; }
5201 if (!convert_to_unicode(&dest)) {
5202 Py_DECREF(src);
5203 return NULL;
5204 }
5205
5206 /* if src is a directory, ensure target_is_directory==1 */
5207 if(
5208 GetFileAttributesExW(
5209 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5210 ))
5211 {
5212 target_is_directory = target_is_directory ||
5213 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5214 }
5215
5216 Py_BEGIN_ALLOW_THREADS
5217 res = Py_CreateSymbolicLinkW(
5218 PyUnicode_AsUnicode(dest),
5219 PyUnicode_AsUnicode(src),
5220 target_is_directory);
5221 Py_END_ALLOW_THREADS
5222 Py_DECREF(src);
5223 Py_DECREF(dest);
5224 if (!res)
5225 {
5226 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5227 }
5228
5229 Py_INCREF(Py_None);
5230 return Py_None;
5231}
5232#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005233
5234#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005235#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5236static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005237system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005238{
5239 ULONG value = 0;
5240
5241 Py_BEGIN_ALLOW_THREADS
5242 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5243 Py_END_ALLOW_THREADS
5244
5245 return value;
5246}
5247
5248static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005249posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005250{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005251 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005252 return Py_BuildValue("ddddd",
5253 (double)0 /* t.tms_utime / HZ */,
5254 (double)0 /* t.tms_stime / HZ */,
5255 (double)0 /* t.tms_cutime / HZ */,
5256 (double)0 /* t.tms_cstime / HZ */,
5257 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005258}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005259#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005260#define NEED_TICKS_PER_SECOND
5261static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005262static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005263posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005264{
Victor Stinner8c62be82010-05-06 00:08:46 +00005265 struct tms t;
5266 clock_t c;
5267 errno = 0;
5268 c = times(&t);
5269 if (c == (clock_t) -1)
5270 return posix_error();
5271 return Py_BuildValue("ddddd",
5272 (double)t.tms_utime / ticks_per_second,
5273 (double)t.tms_stime / ticks_per_second,
5274 (double)t.tms_cutime / ticks_per_second,
5275 (double)t.tms_cstime / ticks_per_second,
5276 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005277}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005278#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005279#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005280
5281
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005282#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005283#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005284static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005285posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005286{
Victor Stinner8c62be82010-05-06 00:08:46 +00005287 FILETIME create, exit, kernel, user;
5288 HANDLE hProc;
5289 hProc = GetCurrentProcess();
5290 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5291 /* The fields of a FILETIME structure are the hi and lo part
5292 of a 64-bit value expressed in 100 nanosecond units.
5293 1e7 is one second in such units; 1e-7 the inverse.
5294 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5295 */
5296 return Py_BuildValue(
5297 "ddddd",
5298 (double)(user.dwHighDateTime*429.4967296 +
5299 user.dwLowDateTime*1e-7),
5300 (double)(kernel.dwHighDateTime*429.4967296 +
5301 kernel.dwLowDateTime*1e-7),
5302 (double)0,
5303 (double)0,
5304 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005305}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005306#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005307
5308#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005309PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005310"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005311Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005312#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005313
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005314
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005315#ifdef HAVE_GETSID
5316PyDoc_STRVAR(posix_getsid__doc__,
5317"getsid(pid) -> sid\n\n\
5318Call the system call getsid().");
5319
5320static PyObject *
5321posix_getsid(PyObject *self, PyObject *args)
5322{
Victor Stinner8c62be82010-05-06 00:08:46 +00005323 pid_t pid;
5324 int sid;
5325 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5326 return NULL;
5327 sid = getsid(pid);
5328 if (sid < 0)
5329 return posix_error();
5330 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005331}
5332#endif /* HAVE_GETSID */
5333
5334
Guido van Rossumb6775db1994-08-01 11:34:53 +00005335#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005336PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005337"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005338Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005339
Barry Warsaw53699e91996-12-10 23:23:01 +00005340static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005341posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005342{
Victor Stinner8c62be82010-05-06 00:08:46 +00005343 if (setsid() < 0)
5344 return posix_error();
5345 Py_INCREF(Py_None);
5346 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005347}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005348#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005349
Guido van Rossumb6775db1994-08-01 11:34:53 +00005350#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005351PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005352"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005353Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005354
Barry Warsaw53699e91996-12-10 23:23:01 +00005355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005356posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005357{
Victor Stinner8c62be82010-05-06 00:08:46 +00005358 pid_t pid;
5359 int pgrp;
5360 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5361 return NULL;
5362 if (setpgid(pid, pgrp) < 0)
5363 return posix_error();
5364 Py_INCREF(Py_None);
5365 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005366}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005367#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005368
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005369
Guido van Rossumb6775db1994-08-01 11:34:53 +00005370#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005371PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005372"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005373Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005374
Barry Warsaw53699e91996-12-10 23:23:01 +00005375static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005376posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005377{
Victor Stinner8c62be82010-05-06 00:08:46 +00005378 int fd;
5379 pid_t pgid;
5380 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5381 return NULL;
5382 pgid = tcgetpgrp(fd);
5383 if (pgid < 0)
5384 return posix_error();
5385 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005386}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005387#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005388
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005389
Guido van Rossumb6775db1994-08-01 11:34:53 +00005390#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005391PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005392"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005393Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005394
Barry Warsaw53699e91996-12-10 23:23:01 +00005395static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005396posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005397{
Victor Stinner8c62be82010-05-06 00:08:46 +00005398 int fd;
5399 pid_t pgid;
5400 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5401 return NULL;
5402 if (tcsetpgrp(fd, pgid) < 0)
5403 return posix_error();
5404 Py_INCREF(Py_None);
5405 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005406}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005407#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005408
Guido van Rossum687dd131993-05-17 08:34:16 +00005409/* Functions acting on file descriptors */
5410
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005411PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005412"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005413Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005414
Barry Warsaw53699e91996-12-10 23:23:01 +00005415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005416posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005417{
Victor Stinner8c62be82010-05-06 00:08:46 +00005418 PyObject *ofile;
5419 char *file;
5420 int flag;
5421 int mode = 0777;
5422 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005423
5424#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005425 PyUnicodeObject *po;
5426 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5427 Py_BEGIN_ALLOW_THREADS
5428 /* PyUnicode_AS_UNICODE OK without thread
5429 lock as it is a simple dereference. */
5430 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5431 Py_END_ALLOW_THREADS
5432 if (fd < 0)
5433 return posix_error();
5434 return PyLong_FromLong((long)fd);
5435 }
5436 /* Drop the argument parsing error as narrow strings
5437 are also valid. */
5438 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005439#endif
5440
Victor Stinner8c62be82010-05-06 00:08:46 +00005441 if (!PyArg_ParseTuple(args, "O&i|i",
5442 PyUnicode_FSConverter, &ofile,
5443 &flag, &mode))
5444 return NULL;
5445 file = PyBytes_AsString(ofile);
5446 Py_BEGIN_ALLOW_THREADS
5447 fd = open(file, flag, mode);
5448 Py_END_ALLOW_THREADS
5449 if (fd < 0)
5450 return posix_error_with_allocated_filename(ofile);
5451 Py_DECREF(ofile);
5452 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005453}
5454
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005455
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005456PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005457"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005458Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005459
Barry Warsaw53699e91996-12-10 23:23:01 +00005460static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005461posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005462{
Victor Stinner8c62be82010-05-06 00:08:46 +00005463 int fd, res;
5464 if (!PyArg_ParseTuple(args, "i:close", &fd))
5465 return NULL;
5466 if (!_PyVerify_fd(fd))
5467 return posix_error();
5468 Py_BEGIN_ALLOW_THREADS
5469 res = close(fd);
5470 Py_END_ALLOW_THREADS
5471 if (res < 0)
5472 return posix_error();
5473 Py_INCREF(Py_None);
5474 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005475}
5476
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005477
Victor Stinner8c62be82010-05-06 00:08:46 +00005478PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005479"closerange(fd_low, fd_high)\n\n\
5480Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5481
5482static PyObject *
5483posix_closerange(PyObject *self, PyObject *args)
5484{
Victor Stinner8c62be82010-05-06 00:08:46 +00005485 int fd_from, fd_to, i;
5486 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5487 return NULL;
5488 Py_BEGIN_ALLOW_THREADS
5489 for (i = fd_from; i < fd_to; i++)
5490 if (_PyVerify_fd(i))
5491 close(i);
5492 Py_END_ALLOW_THREADS
5493 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005494}
5495
5496
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005497PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005498"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005499Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005500
Barry Warsaw53699e91996-12-10 23:23:01 +00005501static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005502posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005503{
Victor Stinner8c62be82010-05-06 00:08:46 +00005504 int fd;
5505 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5506 return NULL;
5507 if (!_PyVerify_fd(fd))
5508 return posix_error();
5509 Py_BEGIN_ALLOW_THREADS
5510 fd = dup(fd);
5511 Py_END_ALLOW_THREADS
5512 if (fd < 0)
5513 return posix_error();
5514 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005515}
5516
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005517
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005518PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005519"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005520Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005521
Barry Warsaw53699e91996-12-10 23:23:01 +00005522static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005523posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005524{
Victor Stinner8c62be82010-05-06 00:08:46 +00005525 int fd, fd2, res;
5526 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5527 return NULL;
5528 if (!_PyVerify_fd_dup2(fd, fd2))
5529 return posix_error();
5530 Py_BEGIN_ALLOW_THREADS
5531 res = dup2(fd, fd2);
5532 Py_END_ALLOW_THREADS
5533 if (res < 0)
5534 return posix_error();
5535 Py_INCREF(Py_None);
5536 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005537}
5538
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005539
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005540PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005541"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005542Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005543
Barry Warsaw53699e91996-12-10 23:23:01 +00005544static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005545posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005546{
Victor Stinner8c62be82010-05-06 00:08:46 +00005547 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005548#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005549 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005550#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005551 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005552#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005553 PyObject *posobj;
5554 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5555 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005556#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005557 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5558 switch (how) {
5559 case 0: how = SEEK_SET; break;
5560 case 1: how = SEEK_CUR; break;
5561 case 2: how = SEEK_END; break;
5562 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005563#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005564
5565#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005566 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005567#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005568 pos = PyLong_Check(posobj) ?
5569 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005570#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005571 if (PyErr_Occurred())
5572 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005573
Victor Stinner8c62be82010-05-06 00:08:46 +00005574 if (!_PyVerify_fd(fd))
5575 return posix_error();
5576 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005577#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005578 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005579#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005580 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005581#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005582 Py_END_ALLOW_THREADS
5583 if (res < 0)
5584 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005585
5586#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005587 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005588#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005589 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005590#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005591}
5592
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005593
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005594PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005595"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005596Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005597
Barry Warsaw53699e91996-12-10 23:23:01 +00005598static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005599posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005600{
Victor Stinner8c62be82010-05-06 00:08:46 +00005601 int fd, size;
5602 Py_ssize_t n;
5603 PyObject *buffer;
5604 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5605 return NULL;
5606 if (size < 0) {
5607 errno = EINVAL;
5608 return posix_error();
5609 }
5610 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5611 if (buffer == NULL)
5612 return NULL;
5613 if (!_PyVerify_fd(fd))
5614 return posix_error();
5615 Py_BEGIN_ALLOW_THREADS
5616 n = read(fd, PyBytes_AS_STRING(buffer), size);
5617 Py_END_ALLOW_THREADS
5618 if (n < 0) {
5619 Py_DECREF(buffer);
5620 return posix_error();
5621 }
5622 if (n != size)
5623 _PyBytes_Resize(&buffer, n);
5624 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005625}
5626
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005627
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005628PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005629"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005630Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005631
Barry Warsaw53699e91996-12-10 23:23:01 +00005632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005633posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005634{
Victor Stinner8c62be82010-05-06 00:08:46 +00005635 Py_buffer pbuf;
5636 int fd;
5637 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005638
Victor Stinner8c62be82010-05-06 00:08:46 +00005639 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5640 return NULL;
5641 if (!_PyVerify_fd(fd))
5642 return posix_error();
5643 Py_BEGIN_ALLOW_THREADS
5644 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5645 Py_END_ALLOW_THREADS
5646 PyBuffer_Release(&pbuf);
5647 if (size < 0)
5648 return posix_error();
5649 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005650}
5651
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005652
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005653PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005654"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005655Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005656
Barry Warsaw53699e91996-12-10 23:23:01 +00005657static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005658posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005659{
Victor Stinner8c62be82010-05-06 00:08:46 +00005660 int fd;
5661 STRUCT_STAT st;
5662 int res;
5663 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5664 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005665#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005666 /* on OpenVMS we must ensure that all bytes are written to the file */
5667 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005668#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005669 if (!_PyVerify_fd(fd))
5670 return posix_error();
5671 Py_BEGIN_ALLOW_THREADS
5672 res = FSTAT(fd, &st);
5673 Py_END_ALLOW_THREADS
5674 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005675#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005676 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005677#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005678 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005679#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005680 }
Tim Peters5aa91602002-01-30 05:46:57 +00005681
Victor Stinner8c62be82010-05-06 00:08:46 +00005682 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005683}
5684
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005685PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005686"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005687Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005688connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005689
5690static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005691posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005692{
Victor Stinner8c62be82010-05-06 00:08:46 +00005693 int fd;
5694 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5695 return NULL;
5696 if (!_PyVerify_fd(fd))
5697 return PyBool_FromLong(0);
5698 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005699}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005700
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005701#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005702PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005703"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005704Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005705
Barry Warsaw53699e91996-12-10 23:23:01 +00005706static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005707posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005708{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005709#if defined(PYOS_OS2)
5710 HFILE read, write;
5711 APIRET rc;
5712
Victor Stinner8c62be82010-05-06 00:08:46 +00005713 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005714 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005715 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005716 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005717 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005718
5719 return Py_BuildValue("(ii)", read, write);
5720#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005721#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005722 int fds[2];
5723 int res;
5724 Py_BEGIN_ALLOW_THREADS
5725 res = pipe(fds);
5726 Py_END_ALLOW_THREADS
5727 if (res != 0)
5728 return posix_error();
5729 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005730#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00005731 HANDLE read, write;
5732 int read_fd, write_fd;
5733 BOOL ok;
5734 Py_BEGIN_ALLOW_THREADS
5735 ok = CreatePipe(&read, &write, NULL, 0);
5736 Py_END_ALLOW_THREADS
5737 if (!ok)
5738 return win32_error("CreatePipe", NULL);
5739 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5740 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5741 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005742#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005743#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005744}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005745#endif /* HAVE_PIPE */
5746
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005747
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005748#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005749PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005750"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005751Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005752
Barry Warsaw53699e91996-12-10 23:23:01 +00005753static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005754posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005755{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005756 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005757 char *filename;
5758 int mode = 0666;
5759 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005760 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5761 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00005762 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005763 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005764 Py_BEGIN_ALLOW_THREADS
5765 res = mkfifo(filename, mode);
5766 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005767 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005768 if (res < 0)
5769 return posix_error();
5770 Py_INCREF(Py_None);
5771 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005772}
5773#endif
5774
5775
Neal Norwitz11690112002-07-30 01:08:28 +00005776#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005777PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005778"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005779Create a filesystem node (file, device special file or named pipe)\n\
5780named filename. mode specifies both the permissions to use and the\n\
5781type of node to be created, being combined (bitwise OR) with one of\n\
5782S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005783device defines the newly created device special file (probably using\n\
5784os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005785
5786
5787static PyObject *
5788posix_mknod(PyObject *self, PyObject *args)
5789{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005790 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005791 char *filename;
5792 int mode = 0600;
5793 int device = 0;
5794 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005795 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5796 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00005797 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005798 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005799 Py_BEGIN_ALLOW_THREADS
5800 res = mknod(filename, mode, device);
5801 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005802 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005803 if (res < 0)
5804 return posix_error();
5805 Py_INCREF(Py_None);
5806 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005807}
5808#endif
5809
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005810#ifdef HAVE_DEVICE_MACROS
5811PyDoc_STRVAR(posix_major__doc__,
5812"major(device) -> major number\n\
5813Extracts a device major number from a raw device number.");
5814
5815static PyObject *
5816posix_major(PyObject *self, PyObject *args)
5817{
Victor Stinner8c62be82010-05-06 00:08:46 +00005818 int device;
5819 if (!PyArg_ParseTuple(args, "i:major", &device))
5820 return NULL;
5821 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005822}
5823
5824PyDoc_STRVAR(posix_minor__doc__,
5825"minor(device) -> minor number\n\
5826Extracts a device minor number from a raw device number.");
5827
5828static PyObject *
5829posix_minor(PyObject *self, PyObject *args)
5830{
Victor Stinner8c62be82010-05-06 00:08:46 +00005831 int device;
5832 if (!PyArg_ParseTuple(args, "i:minor", &device))
5833 return NULL;
5834 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005835}
5836
5837PyDoc_STRVAR(posix_makedev__doc__,
5838"makedev(major, minor) -> device number\n\
5839Composes a raw device number from the major and minor device numbers.");
5840
5841static PyObject *
5842posix_makedev(PyObject *self, PyObject *args)
5843{
Victor Stinner8c62be82010-05-06 00:08:46 +00005844 int major, minor;
5845 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5846 return NULL;
5847 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005848}
5849#endif /* device macros */
5850
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005851
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005852#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005853PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005854"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005855Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005856
Barry Warsaw53699e91996-12-10 23:23:01 +00005857static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005858posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005859{
Victor Stinner8c62be82010-05-06 00:08:46 +00005860 int fd;
5861 off_t length;
5862 int res;
5863 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005864
Victor Stinner8c62be82010-05-06 00:08:46 +00005865 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5866 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005867
5868#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005869 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005870#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005871 length = PyLong_Check(lenobj) ?
5872 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005873#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005874 if (PyErr_Occurred())
5875 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005876
Victor Stinner8c62be82010-05-06 00:08:46 +00005877 Py_BEGIN_ALLOW_THREADS
5878 res = ftruncate(fd, length);
5879 Py_END_ALLOW_THREADS
5880 if (res < 0)
5881 return posix_error();
5882 Py_INCREF(Py_None);
5883 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005884}
5885#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005886
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005887#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005888PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005889"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005890Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005891
Fred Drake762e2061999-08-26 17:23:54 +00005892/* Save putenv() parameters as values here, so we can collect them when they
5893 * get re-set with another call for the same key. */
5894static PyObject *posix_putenv_garbage;
5895
Tim Peters5aa91602002-01-30 05:46:57 +00005896static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005897posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005898{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005899#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005900 wchar_t *s1, *s2;
5901 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005902#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005903 PyObject *os1, *os2;
5904 char *s1, *s2;
5905 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005906#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005907 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005908 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005909
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005910#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005911 if (!PyArg_ParseTuple(args,
5912 "uu:putenv",
5913 &s1, &s2))
5914 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005915#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005916 if (!PyArg_ParseTuple(args,
5917 "O&O&:putenv",
5918 PyUnicode_FSConverter, &os1,
5919 PyUnicode_FSConverter, &os2))
5920 return NULL;
5921 s1 = PyBytes_AsString(os1);
5922 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005923#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005924
5925#if defined(PYOS_OS2)
5926 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5927 APIRET rc;
5928
Guido van Rossumd48f2521997-12-05 22:19:34 +00005929 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005930 if (rc != NO_ERROR) {
5931 os2_error(rc);
5932 goto error;
5933 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005934
5935 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5936 APIRET rc;
5937
Guido van Rossumd48f2521997-12-05 22:19:34 +00005938 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005939 if (rc != NO_ERROR) {
5940 os2_error(rc);
5941 goto error;
5942 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005943 } else {
5944#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005945 /* XXX This can leak memory -- not easy to fix :-( */
5946 /* len includes space for a trailing \0; the size arg to
5947 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005948#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005949 len = wcslen(s1) + wcslen(s2) + 2;
5950 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005951#else
Victor Stinner84ae1182010-05-06 22:05:07 +00005952 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00005953 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005954#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005955 if (newstr == NULL) {
5956 PyErr_NoMemory();
5957 goto error;
5958 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005959#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005960 newenv = PyUnicode_AsUnicode(newstr);
5961 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5962 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005963 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005964 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005965 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005966#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005967 newenv = PyBytes_AS_STRING(newstr);
5968 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5969 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005970 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00005971 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005972 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005973#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005974
Victor Stinner8c62be82010-05-06 00:08:46 +00005975 /* Install the first arg and newstr in posix_putenv_garbage;
5976 * this will cause previous value to be collected. This has to
5977 * happen after the real putenv() call because the old value
5978 * was still accessible until then. */
5979 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00005980#ifdef MS_WINDOWS
5981 PyTuple_GET_ITEM(args, 0),
5982#else
5983 os1,
5984#endif
5985 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005986 /* really not much we can do; just leak */
5987 PyErr_Clear();
5988 }
5989 else {
5990 Py_DECREF(newstr);
5991 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005992
5993#if defined(PYOS_OS2)
5994 }
5995#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005996
Martin v. Löwis011e8422009-05-05 04:43:17 +00005997#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005998 Py_DECREF(os1);
5999 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006000#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006001 Py_RETURN_NONE;
6002
6003error:
6004#ifndef MS_WINDOWS
6005 Py_DECREF(os1);
6006 Py_DECREF(os2);
6007#endif
6008 Py_XDECREF(newstr);
6009 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006010}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006011#endif /* putenv */
6012
Guido van Rossumc524d952001-10-19 01:31:59 +00006013#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006014PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006015"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006016Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006017
6018static PyObject *
6019posix_unsetenv(PyObject *self, PyObject *args)
6020{
Victor Stinner84ae1182010-05-06 22:05:07 +00006021#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006022 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006023
Victor Stinner8c62be82010-05-06 00:08:46 +00006024 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6025 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00006026#else
6027 PyObject *os1;
6028 char *s1;
6029
6030 if (!PyArg_ParseTuple(args, "O&:unsetenv",
6031 PyUnicode_FSConverter, &os1))
6032 return NULL;
6033 s1 = PyBytes_AsString(os1);
6034#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006035
Victor Stinner8c62be82010-05-06 00:08:46 +00006036 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006037
Victor Stinner8c62be82010-05-06 00:08:46 +00006038 /* Remove the key from posix_putenv_garbage;
6039 * this will cause it to be collected. This has to
6040 * happen after the real unsetenv() call because the
6041 * old value was still accessible until then.
6042 */
6043 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006044#ifdef MS_WINDOWS
6045 PyTuple_GET_ITEM(args, 0)
6046#else
6047 os1
6048#endif
6049 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006050 /* really not much we can do; just leak */
6051 PyErr_Clear();
6052 }
Guido van Rossumc524d952001-10-19 01:31:59 +00006053
Victor Stinner84ae1182010-05-06 22:05:07 +00006054#ifndef MS_WINDOWS
6055 Py_DECREF(os1);
6056#endif
6057 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00006058}
6059#endif /* unsetenv */
6060
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006061PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006062"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006063Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006064
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006065static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006066posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006067{
Victor Stinner8c62be82010-05-06 00:08:46 +00006068 int code;
6069 char *message;
6070 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6071 return NULL;
6072 message = strerror(code);
6073 if (message == NULL) {
6074 PyErr_SetString(PyExc_ValueError,
6075 "strerror() argument out of range");
6076 return NULL;
6077 }
6078 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006079}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006080
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006081
Guido van Rossumc9641791998-08-04 15:26:23 +00006082#ifdef HAVE_SYS_WAIT_H
6083
Fred Drake106c1a02002-04-23 15:58:02 +00006084#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006085PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006086"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006087Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006088
6089static PyObject *
6090posix_WCOREDUMP(PyObject *self, PyObject *args)
6091{
Victor Stinner8c62be82010-05-06 00:08:46 +00006092 WAIT_TYPE status;
6093 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006094
Victor Stinner8c62be82010-05-06 00:08:46 +00006095 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6096 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006097
Victor Stinner8c62be82010-05-06 00:08:46 +00006098 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006099}
6100#endif /* WCOREDUMP */
6101
6102#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006103PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006104"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006105Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006106job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006107
6108static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006109posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006110{
Victor Stinner8c62be82010-05-06 00:08:46 +00006111 WAIT_TYPE status;
6112 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006113
Victor Stinner8c62be82010-05-06 00:08:46 +00006114 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6115 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006116
Victor Stinner8c62be82010-05-06 00:08:46 +00006117 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006118}
6119#endif /* WIFCONTINUED */
6120
Guido van Rossumc9641791998-08-04 15:26:23 +00006121#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006122PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006123"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006124Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006125
6126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006127posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006128{
Victor Stinner8c62be82010-05-06 00:08:46 +00006129 WAIT_TYPE status;
6130 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006131
Victor Stinner8c62be82010-05-06 00:08:46 +00006132 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6133 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006134
Victor Stinner8c62be82010-05-06 00:08:46 +00006135 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006136}
6137#endif /* WIFSTOPPED */
6138
6139#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006140PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006141"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006142Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006143
6144static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006145posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006146{
Victor Stinner8c62be82010-05-06 00:08:46 +00006147 WAIT_TYPE status;
6148 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006149
Victor Stinner8c62be82010-05-06 00:08:46 +00006150 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6151 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006152
Victor Stinner8c62be82010-05-06 00:08:46 +00006153 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006154}
6155#endif /* WIFSIGNALED */
6156
6157#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006158PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006159"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006160Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006161system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006162
6163static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006164posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006165{
Victor Stinner8c62be82010-05-06 00:08:46 +00006166 WAIT_TYPE status;
6167 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006168
Victor Stinner8c62be82010-05-06 00:08:46 +00006169 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6170 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006171
Victor Stinner8c62be82010-05-06 00:08:46 +00006172 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006173}
6174#endif /* WIFEXITED */
6175
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006176#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006177PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006178"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006179Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006180
6181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006182posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006183{
Victor Stinner8c62be82010-05-06 00:08:46 +00006184 WAIT_TYPE status;
6185 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006186
Victor Stinner8c62be82010-05-06 00:08:46 +00006187 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6188 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006189
Victor Stinner8c62be82010-05-06 00:08:46 +00006190 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006191}
6192#endif /* WEXITSTATUS */
6193
6194#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006195PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006196"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006197Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006198value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006199
6200static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006201posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006202{
Victor Stinner8c62be82010-05-06 00:08:46 +00006203 WAIT_TYPE status;
6204 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006205
Victor Stinner8c62be82010-05-06 00:08:46 +00006206 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6207 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006208
Victor Stinner8c62be82010-05-06 00:08:46 +00006209 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006210}
6211#endif /* WTERMSIG */
6212
6213#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006214PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006215"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006216Return the signal that stopped the process that provided\n\
6217the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006218
6219static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006220posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006221{
Victor Stinner8c62be82010-05-06 00:08:46 +00006222 WAIT_TYPE status;
6223 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006224
Victor Stinner8c62be82010-05-06 00:08:46 +00006225 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6226 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006227
Victor Stinner8c62be82010-05-06 00:08:46 +00006228 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006229}
6230#endif /* WSTOPSIG */
6231
6232#endif /* HAVE_SYS_WAIT_H */
6233
6234
Thomas Wouters477c8d52006-05-27 19:21:47 +00006235#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006236#ifdef _SCO_DS
6237/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6238 needed definitions in sys/statvfs.h */
6239#define _SVID3
6240#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006241#include <sys/statvfs.h>
6242
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006243static PyObject*
6244_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006245 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6246 if (v == NULL)
6247 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006248
6249#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006250 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6251 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6252 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6253 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6254 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6255 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6256 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6257 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6258 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6259 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006260#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006261 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6262 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6263 PyStructSequence_SET_ITEM(v, 2,
6264 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6265 PyStructSequence_SET_ITEM(v, 3,
6266 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6267 PyStructSequence_SET_ITEM(v, 4,
6268 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6269 PyStructSequence_SET_ITEM(v, 5,
6270 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6271 PyStructSequence_SET_ITEM(v, 6,
6272 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6273 PyStructSequence_SET_ITEM(v, 7,
6274 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6275 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6276 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006277#endif
6278
Victor Stinner8c62be82010-05-06 00:08:46 +00006279 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006280}
6281
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006282PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006283"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006284Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006285
6286static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006287posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006288{
Victor Stinner8c62be82010-05-06 00:08:46 +00006289 int fd, res;
6290 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006291
Victor Stinner8c62be82010-05-06 00:08:46 +00006292 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6293 return NULL;
6294 Py_BEGIN_ALLOW_THREADS
6295 res = fstatvfs(fd, &st);
6296 Py_END_ALLOW_THREADS
6297 if (res != 0)
6298 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006299
Victor Stinner8c62be82010-05-06 00:08:46 +00006300 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006301}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006302#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006303
6304
Thomas Wouters477c8d52006-05-27 19:21:47 +00006305#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006306#include <sys/statvfs.h>
6307
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006308PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006309"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006310Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006311
6312static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006313posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006314{
Victor Stinner8c62be82010-05-06 00:08:46 +00006315 char *path;
6316 int res;
6317 struct statvfs st;
6318 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6319 return NULL;
6320 Py_BEGIN_ALLOW_THREADS
6321 res = statvfs(path, &st);
6322 Py_END_ALLOW_THREADS
6323 if (res != 0)
6324 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006325
Victor Stinner8c62be82010-05-06 00:08:46 +00006326 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006327}
6328#endif /* HAVE_STATVFS */
6329
Fred Drakec9680921999-12-13 16:37:25 +00006330/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6331 * It maps strings representing configuration variable names to
6332 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006333 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006334 * rarely-used constants. There are three separate tables that use
6335 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006336 *
6337 * This code is always included, even if none of the interfaces that
6338 * need it are included. The #if hackery needed to avoid it would be
6339 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006340 */
6341struct constdef {
6342 char *name;
6343 long value;
6344};
6345
Fred Drake12c6e2d1999-12-14 21:25:03 +00006346static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006347conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006348 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006349{
Christian Heimes217cfd12007-12-02 14:31:20 +00006350 if (PyLong_Check(arg)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006351 *valuep = PyLong_AS_LONG(arg);
6352 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006353 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006354 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 /* look up the value in the table using a binary search */
6356 size_t lo = 0;
6357 size_t mid;
6358 size_t hi = tablesize;
6359 int cmp;
6360 const char *confname;
6361 if (!PyUnicode_Check(arg)) {
6362 PyErr_SetString(PyExc_TypeError,
6363 "configuration names must be strings or integers");
Guido van Rossumbce56a62007-05-10 18:04:33 +00006364 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006365 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006366 confname = _PyUnicode_AsString(arg);
6367 if (confname == NULL)
6368 return 0;
6369 while (lo < hi) {
6370 mid = (lo + hi) / 2;
6371 cmp = strcmp(confname, table[mid].name);
6372 if (cmp < 0)
6373 hi = mid;
6374 else if (cmp > 0)
6375 lo = mid + 1;
6376 else {
6377 *valuep = table[mid].value;
6378 return 1;
6379 }
6380 }
6381 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6382 return 0;
6383 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006384}
6385
6386
6387#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6388static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006389#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006390 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006391#endif
6392#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006393 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006394#endif
Fred Drakec9680921999-12-13 16:37:25 +00006395#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006396 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006397#endif
6398#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006399 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006400#endif
6401#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006402 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006403#endif
6404#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006406#endif
6407#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006408 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006409#endif
6410#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006411 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006412#endif
6413#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006414 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006415#endif
6416#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006417 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006418#endif
6419#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006420 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006421#endif
6422#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006423 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006424#endif
6425#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006426 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006427#endif
6428#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006429 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006430#endif
6431#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006432 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006433#endif
6434#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006435 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006436#endif
6437#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006438 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006439#endif
6440};
6441
Fred Drakec9680921999-12-13 16:37:25 +00006442static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006443conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006444{
6445 return conv_confname(arg, valuep, posix_constants_pathconf,
6446 sizeof(posix_constants_pathconf)
6447 / sizeof(struct constdef));
6448}
6449#endif
6450
6451#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006452PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006453"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006454Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006455If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006456
6457static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006458posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006459{
6460 PyObject *result = NULL;
6461 int name, fd;
6462
Fred Drake12c6e2d1999-12-14 21:25:03 +00006463 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6464 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006465 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006466
Victor Stinner8c62be82010-05-06 00:08:46 +00006467 errno = 0;
6468 limit = fpathconf(fd, name);
6469 if (limit == -1 && errno != 0)
6470 posix_error();
6471 else
6472 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006473 }
6474 return result;
6475}
6476#endif
6477
6478
6479#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006480PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006481"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006482Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006483If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006484
6485static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006486posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006487{
6488 PyObject *result = NULL;
6489 int name;
6490 char *path;
6491
6492 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6493 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006494 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006495
Victor Stinner8c62be82010-05-06 00:08:46 +00006496 errno = 0;
6497 limit = pathconf(path, name);
6498 if (limit == -1 && errno != 0) {
6499 if (errno == EINVAL)
6500 /* could be a path or name problem */
6501 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006502 else
Victor Stinner8c62be82010-05-06 00:08:46 +00006503 posix_error_with_filename(path);
6504 }
6505 else
6506 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006507 }
6508 return result;
6509}
6510#endif
6511
6512#ifdef HAVE_CONFSTR
6513static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006514#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006515 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006516#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006517#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006518 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006519#endif
6520#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006521 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006522#endif
Fred Draked86ed291999-12-15 15:34:33 +00006523#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006524 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006525#endif
6526#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006527 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006528#endif
6529#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006530 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006531#endif
6532#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006533 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006534#endif
Fred Drakec9680921999-12-13 16:37:25 +00006535#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006536 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006537#endif
6538#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006540#endif
6541#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006542 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006543#endif
6544#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006545 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006546#endif
6547#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006548 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006549#endif
6550#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006551 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006552#endif
6553#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006554 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006555#endif
6556#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006557 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006558#endif
Fred Draked86ed291999-12-15 15:34:33 +00006559#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006560 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006561#endif
Fred Drakec9680921999-12-13 16:37:25 +00006562#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006563 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006564#endif
Fred Draked86ed291999-12-15 15:34:33 +00006565#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006566 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006567#endif
6568#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006569 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006570#endif
6571#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006572 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006573#endif
6574#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006575 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006576#endif
Fred Drakec9680921999-12-13 16:37:25 +00006577#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006579#endif
6580#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006581 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006582#endif
6583#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006584 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006585#endif
6586#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006587 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006588#endif
6589#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006590 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006591#endif
6592#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006593 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006594#endif
6595#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006596 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006597#endif
6598#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006599 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006600#endif
6601#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006602 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006603#endif
6604#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006606#endif
6607#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006608 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006609#endif
6610#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006611 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006612#endif
6613#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006614 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006615#endif
6616#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006617 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006618#endif
6619#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006620 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006621#endif
6622#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006623 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006624#endif
Fred Draked86ed291999-12-15 15:34:33 +00006625#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006626 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006627#endif
6628#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006629 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006630#endif
6631#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006632 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006633#endif
6634#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006635 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006636#endif
6637#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006638 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006639#endif
6640#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006641 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006642#endif
6643#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006644 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006645#endif
6646#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006647 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006648#endif
6649#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006650 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006651#endif
6652#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006653 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006654#endif
6655#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006656 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006657#endif
6658#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006660#endif
6661#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006662 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006663#endif
Fred Drakec9680921999-12-13 16:37:25 +00006664};
6665
6666static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006667conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006668{
6669 return conv_confname(arg, valuep, posix_constants_confstr,
6670 sizeof(posix_constants_confstr)
6671 / sizeof(struct constdef));
6672}
6673
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006674PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006675"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006676Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006677
6678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006679posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006680{
6681 PyObject *result = NULL;
6682 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00006683 char buffer[255];
Victor Stinner8c62be82010-05-06 00:08:46 +00006684 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006685
Victor Stinnercb043522010-09-10 23:49:04 +00006686 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
6687 return NULL;
6688
6689 errno = 0;
6690 len = confstr(name, buffer, sizeof(buffer));
6691 if (len == 0) {
6692 if (errno) {
6693 posix_error();
6694 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00006695 }
6696 else {
Victor Stinnercb043522010-09-10 23:49:04 +00006697 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00006698 }
6699 }
Victor Stinnercb043522010-09-10 23:49:04 +00006700
6701 if ((unsigned int)len >= sizeof(buffer)) {
6702 char *buf = PyMem_Malloc(len);
6703 if (buf == NULL)
6704 return PyErr_NoMemory();
6705 confstr(name, buf, len);
6706 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
6707 PyMem_Free(buf);
6708 }
6709 else
6710 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006711 return result;
6712}
6713#endif
6714
6715
6716#ifdef HAVE_SYSCONF
6717static struct constdef posix_constants_sysconf[] = {
6718#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00006719 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006720#endif
6721#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00006722 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006723#endif
6724#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006726#endif
6727#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006728 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006729#endif
6730#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006731 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006732#endif
6733#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006735#endif
6736#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006738#endif
6739#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006740 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006741#endif
6742#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00006743 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006744#endif
6745#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006746 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006747#endif
Fred Draked86ed291999-12-15 15:34:33 +00006748#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006749 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006750#endif
6751#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00006752 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006753#endif
Fred Drakec9680921999-12-13 16:37:25 +00006754#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006755 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006756#endif
Fred Drakec9680921999-12-13 16:37:25 +00006757#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006758 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006759#endif
6760#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006762#endif
6763#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006764 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006765#endif
6766#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006767 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006768#endif
6769#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006770 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006771#endif
Fred Draked86ed291999-12-15 15:34:33 +00006772#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006774#endif
Fred Drakec9680921999-12-13 16:37:25 +00006775#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006776 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006777#endif
6778#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006780#endif
6781#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006782 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006783#endif
6784#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006786#endif
6787#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006788 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006789#endif
Fred Draked86ed291999-12-15 15:34:33 +00006790#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006792#endif
Fred Drakec9680921999-12-13 16:37:25 +00006793#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006795#endif
6796#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006798#endif
6799#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006801#endif
6802#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006804#endif
6805#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006807#endif
6808#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006810#endif
6811#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006813#endif
6814#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006815 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006816#endif
6817#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006818 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006819#endif
6820#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006822#endif
6823#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006825#endif
6826#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006827 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006828#endif
6829#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006831#endif
6832#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006833 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006834#endif
6835#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006836 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006837#endif
6838#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006839 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006840#endif
6841#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006842 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006843#endif
6844#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006846#endif
6847#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006848 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006849#endif
6850#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006852#endif
6853#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006854 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006855#endif
6856#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006857 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006858#endif
6859#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006860 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006861#endif
Fred Draked86ed291999-12-15 15:34:33 +00006862#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00006863 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006864#endif
Fred Drakec9680921999-12-13 16:37:25 +00006865#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006866 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006867#endif
6868#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006869 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006870#endif
6871#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006872 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006873#endif
Fred Draked86ed291999-12-15 15:34:33 +00006874#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006875 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006876#endif
Fred Drakec9680921999-12-13 16:37:25 +00006877#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00006878 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006879#endif
Fred Draked86ed291999-12-15 15:34:33 +00006880#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00006881 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006882#endif
6883#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006885#endif
Fred Drakec9680921999-12-13 16:37:25 +00006886#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006887 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006888#endif
6889#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006890 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006891#endif
6892#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006893 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006894#endif
6895#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006896 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006897#endif
Fred Draked86ed291999-12-15 15:34:33 +00006898#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00006899 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006900#endif
Fred Drakec9680921999-12-13 16:37:25 +00006901#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00006902 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006903#endif
6904#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00006905 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006906#endif
6907#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006908 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006909#endif
6910#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006912#endif
6913#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00006914 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006915#endif
6916#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00006917 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006918#endif
6919#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00006920 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006921#endif
Fred Draked86ed291999-12-15 15:34:33 +00006922#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00006923 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006924#endif
Fred Drakec9680921999-12-13 16:37:25 +00006925#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006926 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006927#endif
6928#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006929 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006930#endif
Fred Draked86ed291999-12-15 15:34:33 +00006931#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006932 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006933#endif
Fred Drakec9680921999-12-13 16:37:25 +00006934#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006935 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006936#endif
6937#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006938 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006939#endif
6940#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006941 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006942#endif
6943#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006944 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006945#endif
6946#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006947 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006948#endif
6949#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006950 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006951#endif
6952#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006953 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006954#endif
6955#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006956 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00006957#endif
6958#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00006959 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00006960#endif
Fred Draked86ed291999-12-15 15:34:33 +00006961#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006962 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00006963#endif
6964#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00006965 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00006966#endif
Fred Drakec9680921999-12-13 16:37:25 +00006967#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00006968 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00006969#endif
6970#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006971 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006972#endif
6973#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006975#endif
6976#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00006977 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00006978#endif
6979#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006980 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006981#endif
6982#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006983 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006984#endif
6985#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00006987#endif
6988#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00006989 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00006990#endif
6991#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00006992 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00006993#endif
6994#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00006995 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00006996#endif
6997#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00006998 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00006999#endif
7000#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007001 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00007002#endif
7003#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007004 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00007005#endif
7006#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00007007 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00007008#endif
7009#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00007010 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00007011#endif
7012#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00007013 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00007014#endif
7015#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00007016 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00007017#endif
7018#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007019 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007020#endif
7021#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007022 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007023#endif
7024#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00007025 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00007026#endif
7027#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007028 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007029#endif
7030#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007031 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007032#endif
7033#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00007034 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00007035#endif
7036#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007037 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007038#endif
7039#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007040 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007041#endif
7042#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007043 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00007044#endif
7045#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00007047#endif
7048#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007049 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007050#endif
7051#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007052 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007053#endif
7054#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007055 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00007056#endif
7057#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007058 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007059#endif
7060#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007061 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007062#endif
7063#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007064 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007065#endif
7066#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007067 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007068#endif
7069#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007070 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007071#endif
Fred Draked86ed291999-12-15 15:34:33 +00007072#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00007073 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00007074#endif
Fred Drakec9680921999-12-13 16:37:25 +00007075#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00007076 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00007077#endif
7078#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007079 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007080#endif
7081#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00007082 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00007083#endif
7084#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007085 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007086#endif
7087#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007088 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007089#endif
7090#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007091 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007092#endif
7093#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00007094 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00007095#endif
7096#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007097 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007098#endif
7099#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007100 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007101#endif
7102#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007103 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007104#endif
7105#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007106 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007107#endif
7108#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007109 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00007110#endif
7111#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007112 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00007113#endif
7114#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00007115 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00007116#endif
7117#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007118 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007119#endif
7120#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007121 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007122#endif
7123#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007124 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007125#endif
7126#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007127 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00007128#endif
7129#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007130 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007131#endif
7132#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007133 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007134#endif
7135#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007136 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007137#endif
7138#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007139 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007140#endif
7141#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007142 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007143#endif
7144#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007145 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007146#endif
7147#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007148 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007149#endif
7150#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007151 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007152#endif
7153#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007154 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007155#endif
7156#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007157 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007158#endif
7159#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007160 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007161#endif
7162#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007163 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007164#endif
7165#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007166 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007167#endif
7168#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007169 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007170#endif
7171#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007172 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007173#endif
7174#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007175 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007176#endif
7177#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007178 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007179#endif
7180#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007181 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007182#endif
7183#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007184 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007185#endif
7186#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007187 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007188#endif
7189#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007190 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007191#endif
7192#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007193 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007194#endif
7195#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007196 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007197#endif
7198#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007199 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007200#endif
7201#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007202 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007203#endif
7204#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007205 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007206#endif
7207#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007208 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007209#endif
7210};
7211
7212static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007213conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007214{
7215 return conv_confname(arg, valuep, posix_constants_sysconf,
7216 sizeof(posix_constants_sysconf)
7217 / sizeof(struct constdef));
7218}
7219
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007220PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007221"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007222Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007223
7224static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007225posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007226{
7227 PyObject *result = NULL;
7228 int name;
7229
7230 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7231 int value;
7232
7233 errno = 0;
7234 value = sysconf(name);
7235 if (value == -1 && errno != 0)
7236 posix_error();
7237 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007238 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007239 }
7240 return result;
7241}
7242#endif
7243
7244
Fred Drakebec628d1999-12-15 18:31:10 +00007245/* This code is used to ensure that the tables of configuration value names
7246 * are in sorted order as required by conv_confname(), and also to build the
7247 * the exported dictionaries that are used to publish information about the
7248 * names available on the host platform.
7249 *
7250 * Sorting the table at runtime ensures that the table is properly ordered
7251 * when used, even for platforms we're not able to test on. It also makes
7252 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007253 */
Fred Drakebec628d1999-12-15 18:31:10 +00007254
7255static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007256cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007257{
7258 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007259 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007260 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007261 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007262
7263 return strcmp(c1->name, c2->name);
7264}
7265
7266static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007267setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007268 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007269{
Fred Drakebec628d1999-12-15 18:31:10 +00007270 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007271 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007272
7273 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7274 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007275 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007276 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007277
Barry Warsaw3155db32000-04-13 15:20:40 +00007278 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007279 PyObject *o = PyLong_FromLong(table[i].value);
7280 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7281 Py_XDECREF(o);
7282 Py_DECREF(d);
7283 return -1;
7284 }
7285 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007286 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007287 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007288}
7289
Fred Drakebec628d1999-12-15 18:31:10 +00007290/* Return -1 on failure, 0 on success. */
7291static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007292setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007293{
7294#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007295 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007296 sizeof(posix_constants_pathconf)
7297 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007298 "pathconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007299 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007300#endif
7301#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007302 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007303 sizeof(posix_constants_confstr)
7304 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007305 "confstr_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007306 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007307#endif
7308#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007309 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007310 sizeof(posix_constants_sysconf)
7311 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007312 "sysconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007313 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007314#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007315 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007316}
Fred Draked86ed291999-12-15 15:34:33 +00007317
7318
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007319PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007320"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007321Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007322in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007323
7324static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007325posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007326{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007327 abort();
7328 /*NOTREACHED*/
7329 Py_FatalError("abort() called from Python code didn't abort!");
7330 return NULL;
7331}
Fred Drakebec628d1999-12-15 18:31:10 +00007332
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007333#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007334PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007335"startfile(filepath [, operation]) - Start a file with its associated\n\
7336application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007337\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007338When \"operation\" is not specified or \"open\", this acts like\n\
7339double-clicking the file in Explorer, or giving the file name as an\n\
7340argument to the DOS \"start\" command: the file is opened with whatever\n\
7341application (if any) its extension is associated.\n\
7342When another \"operation\" is given, it specifies what should be done with\n\
7343the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007344\n\
7345startfile returns as soon as the associated application is launched.\n\
7346There is no option to wait for the application to close, and no way\n\
7347to retrieve the application's exit status.\n\
7348\n\
7349The filepath is relative to the current directory. If you want to use\n\
7350an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007351the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007352
7353static PyObject *
7354win32_startfile(PyObject *self, PyObject *args)
7355{
Victor Stinner8c62be82010-05-06 00:08:46 +00007356 PyObject *ofilepath;
7357 char *filepath;
7358 char *operation = NULL;
7359 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007360
Victor Stinner8c62be82010-05-06 00:08:46 +00007361 PyObject *unipath, *woperation = NULL;
7362 if (!PyArg_ParseTuple(args, "U|s:startfile",
7363 &unipath, &operation)) {
7364 PyErr_Clear();
7365 goto normal;
7366 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007367
Victor Stinner8c62be82010-05-06 00:08:46 +00007368 if (operation) {
7369 woperation = PyUnicode_DecodeASCII(operation,
7370 strlen(operation), NULL);
7371 if (!woperation) {
7372 PyErr_Clear();
7373 operation = NULL;
7374 goto normal;
7375 }
7376 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007377
Victor Stinner8c62be82010-05-06 00:08:46 +00007378 Py_BEGIN_ALLOW_THREADS
7379 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7380 PyUnicode_AS_UNICODE(unipath),
7381 NULL, NULL, SW_SHOWNORMAL);
7382 Py_END_ALLOW_THREADS
7383
7384 Py_XDECREF(woperation);
7385 if (rc <= (HINSTANCE)32) {
7386 PyObject *errval = win32_error_unicode("startfile",
7387 PyUnicode_AS_UNICODE(unipath));
7388 return errval;
7389 }
7390 Py_INCREF(Py_None);
7391 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007392
7393normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007394 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7395 PyUnicode_FSConverter, &ofilepath,
7396 &operation))
7397 return NULL;
7398 filepath = PyBytes_AsString(ofilepath);
7399 Py_BEGIN_ALLOW_THREADS
7400 rc = ShellExecute((HWND)0, operation, filepath,
7401 NULL, NULL, SW_SHOWNORMAL);
7402 Py_END_ALLOW_THREADS
7403 if (rc <= (HINSTANCE)32) {
7404 PyObject *errval = win32_error("startfile", filepath);
7405 Py_DECREF(ofilepath);
7406 return errval;
7407 }
7408 Py_DECREF(ofilepath);
7409 Py_INCREF(Py_None);
7410 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007411}
7412#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007413
Martin v. Löwis438b5342002-12-27 10:16:42 +00007414#ifdef HAVE_GETLOADAVG
7415PyDoc_STRVAR(posix_getloadavg__doc__,
7416"getloadavg() -> (float, float, float)\n\n\
7417Return the number of processes in the system run queue averaged over\n\
7418the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7419was unobtainable");
7420
7421static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007422posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007423{
7424 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007425 if (getloadavg(loadavg, 3)!=3) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007426 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7427 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007428 } else
Victor Stinner8c62be82010-05-06 00:08:46 +00007429 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007430}
7431#endif
7432
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007433#ifdef MS_WINDOWS
7434
7435PyDoc_STRVAR(win32_urandom__doc__,
7436"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007437Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007438
7439typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7440 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7441 DWORD dwFlags );
7442typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7443 BYTE *pbBuffer );
7444
7445static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007446/* This handle is never explicitly released. Instead, the operating
7447 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007448static HCRYPTPROV hCryptProv = 0;
7449
Tim Peters4ad82172004-08-30 17:02:04 +00007450static PyObject*
7451win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007452{
Victor Stinner8c62be82010-05-06 00:08:46 +00007453 int howMany;
7454 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007455
Victor Stinner8c62be82010-05-06 00:08:46 +00007456 /* Read arguments */
7457 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7458 return NULL;
7459 if (howMany < 0)
7460 return PyErr_Format(PyExc_ValueError,
7461 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007462
Victor Stinner8c62be82010-05-06 00:08:46 +00007463 if (hCryptProv == 0) {
7464 HINSTANCE hAdvAPI32 = NULL;
7465 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007466
Victor Stinner8c62be82010-05-06 00:08:46 +00007467 /* Obtain handle to the DLL containing CryptoAPI
7468 This should not fail */
7469 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7470 if(hAdvAPI32 == NULL)
7471 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007472
Victor Stinner8c62be82010-05-06 00:08:46 +00007473 /* Obtain pointers to the CryptoAPI functions
7474 This will fail on some early versions of Win95 */
7475 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7476 hAdvAPI32,
7477 "CryptAcquireContextA");
7478 if (pCryptAcquireContext == NULL)
7479 return PyErr_Format(PyExc_NotImplementedError,
7480 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007481
Victor Stinner8c62be82010-05-06 00:08:46 +00007482 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7483 hAdvAPI32, "CryptGenRandom");
7484 if (pCryptGenRandom == NULL)
7485 return PyErr_Format(PyExc_NotImplementedError,
7486 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007487
Victor Stinner8c62be82010-05-06 00:08:46 +00007488 /* Acquire context */
7489 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7490 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7491 return win32_error("CryptAcquireContext", NULL);
7492 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007493
Victor Stinner8c62be82010-05-06 00:08:46 +00007494 /* Allocate bytes */
7495 result = PyBytes_FromStringAndSize(NULL, howMany);
7496 if (result != NULL) {
7497 /* Get random data */
7498 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7499 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7500 PyBytes_AS_STRING(result))) {
7501 Py_DECREF(result);
7502 return win32_error("CryptGenRandom", NULL);
7503 }
7504 }
7505 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007506}
7507#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007508
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007509PyDoc_STRVAR(device_encoding__doc__,
7510"device_encoding(fd) -> str\n\n\
7511Return a string describing the encoding of the device\n\
7512if the output is a terminal; else return None.");
7513
7514static PyObject *
7515device_encoding(PyObject *self, PyObject *args)
7516{
Victor Stinner8c62be82010-05-06 00:08:46 +00007517 int fd;
7518 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7519 return NULL;
7520 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7521 Py_INCREF(Py_None);
7522 return Py_None;
7523 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007524#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007525 if (fd == 0) {
7526 char buf[100];
7527 sprintf(buf, "cp%d", GetConsoleCP());
7528 return PyUnicode_FromString(buf);
7529 }
7530 if (fd == 1 || fd == 2) {
7531 char buf[100];
7532 sprintf(buf, "cp%d", GetConsoleOutputCP());
7533 return PyUnicode_FromString(buf);
7534 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007535#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007536 {
7537 char *codeset = nl_langinfo(CODESET);
7538 if (codeset != NULL && codeset[0] != 0)
7539 return PyUnicode_FromString(codeset);
7540 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007541#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007542 Py_INCREF(Py_None);
7543 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007544}
7545
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007546#ifdef __VMS
7547/* Use openssl random routine */
7548#include <openssl/rand.h>
7549PyDoc_STRVAR(vms_urandom__doc__,
7550"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007551Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007552
7553static PyObject*
7554vms_urandom(PyObject *self, PyObject *args)
7555{
Victor Stinner8c62be82010-05-06 00:08:46 +00007556 int howMany;
7557 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007558
Victor Stinner8c62be82010-05-06 00:08:46 +00007559 /* Read arguments */
7560 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7561 return NULL;
7562 if (howMany < 0)
7563 return PyErr_Format(PyExc_ValueError,
7564 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007565
Victor Stinner8c62be82010-05-06 00:08:46 +00007566 /* Allocate bytes */
7567 result = PyBytes_FromStringAndSize(NULL, howMany);
7568 if (result != NULL) {
7569 /* Get random data */
7570 if (RAND_pseudo_bytes((unsigned char*)
7571 PyBytes_AS_STRING(result),
7572 howMany) < 0) {
7573 Py_DECREF(result);
7574 return PyErr_Format(PyExc_ValueError,
7575 "RAND_pseudo_bytes");
7576 }
7577 }
7578 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007579}
7580#endif
7581
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007582#ifdef HAVE_SETRESUID
7583PyDoc_STRVAR(posix_setresuid__doc__,
7584"setresuid(ruid, euid, suid)\n\n\
7585Set the current process's real, effective, and saved user ids.");
7586
7587static PyObject*
7588posix_setresuid (PyObject *self, PyObject *args)
7589{
Victor Stinner8c62be82010-05-06 00:08:46 +00007590 /* We assume uid_t is no larger than a long. */
7591 long ruid, euid, suid;
7592 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7593 return NULL;
7594 if (setresuid(ruid, euid, suid) < 0)
7595 return posix_error();
7596 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007597}
7598#endif
7599
7600#ifdef HAVE_SETRESGID
7601PyDoc_STRVAR(posix_setresgid__doc__,
7602"setresgid(rgid, egid, sgid)\n\n\
7603Set the current process's real, effective, and saved group ids.");
7604
7605static PyObject*
7606posix_setresgid (PyObject *self, PyObject *args)
7607{
Victor Stinner8c62be82010-05-06 00:08:46 +00007608 /* We assume uid_t is no larger than a long. */
7609 long rgid, egid, sgid;
7610 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7611 return NULL;
7612 if (setresgid(rgid, egid, sgid) < 0)
7613 return posix_error();
7614 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007615}
7616#endif
7617
7618#ifdef HAVE_GETRESUID
7619PyDoc_STRVAR(posix_getresuid__doc__,
7620"getresuid() -> (ruid, euid, suid)\n\n\
7621Get tuple of the current process's real, effective, and saved user ids.");
7622
7623static PyObject*
7624posix_getresuid (PyObject *self, PyObject *noargs)
7625{
Victor Stinner8c62be82010-05-06 00:08:46 +00007626 uid_t ruid, euid, suid;
7627 long l_ruid, l_euid, l_suid;
7628 if (getresuid(&ruid, &euid, &suid) < 0)
7629 return posix_error();
7630 /* Force the values into long's as we don't know the size of uid_t. */
7631 l_ruid = ruid;
7632 l_euid = euid;
7633 l_suid = suid;
7634 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007635}
7636#endif
7637
7638#ifdef HAVE_GETRESGID
7639PyDoc_STRVAR(posix_getresgid__doc__,
7640"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00007641Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007642
7643static PyObject*
7644posix_getresgid (PyObject *self, PyObject *noargs)
7645{
Victor Stinner8c62be82010-05-06 00:08:46 +00007646 uid_t rgid, egid, sgid;
7647 long l_rgid, l_egid, l_sgid;
7648 if (getresgid(&rgid, &egid, &sgid) < 0)
7649 return posix_error();
7650 /* Force the values into long's as we don't know the size of uid_t. */
7651 l_rgid = rgid;
7652 l_egid = egid;
7653 l_sgid = sgid;
7654 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007655}
7656#endif
7657
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007658static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007659 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007660#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007661 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007662#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007663 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007664#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007665 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007666#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007667 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007668#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007669 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007670#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007671#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007672 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007673#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007674#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007675 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007676#endif /* HAVE_LCHMOD */
7677#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007678 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007679#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007680#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007681 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007682#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007683#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007684 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007685#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007686#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007687 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007688#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007689#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007690 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007691#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007692#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00007693 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7694 METH_NOARGS, posix_getcwd__doc__},
7695 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7696 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007697#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007698#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007699 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007700#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00007701 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7702 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7703 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007704#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00007705 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007706#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007707#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007708 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007709#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007710#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007711 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007712#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007713 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7714 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7715 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00007716 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007717#ifdef HAVE_SYMLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007718 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007719#endif /* HAVE_SYMLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007720#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin74e45612010-07-09 15:58:59 +00007721 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
7722 win_symlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007723#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007724#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007726#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007727 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007728#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007729 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007730#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7732 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7733 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007734#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00007735 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007736#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00007737 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007738#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00007739 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7740 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007741#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007742#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00007743 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7744 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007745#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00007746 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7747 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007748#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007749#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007750#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00007751 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007752#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007753#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007755#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007756#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00007757 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007758#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007759#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007760 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007761#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007762#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007763 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007764#endif /* HAVE_GETEGID */
7765#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007766 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007767#endif /* HAVE_GETEUID */
7768#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007770#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007771#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007772 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007773#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007774 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007775#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007776 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007777#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007778#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007779 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007780#endif /* HAVE_GETPPID */
7781#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007782 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007783#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007784#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007785 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007786#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007787#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00007788 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007789#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007790#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007792#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007793#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007795#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007796#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007797 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7798 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007799#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007800#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007802#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007803#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007805#endif /* HAVE_SETEUID */
7806#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007807 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007808#endif /* HAVE_SETEGID */
7809#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007811#endif /* HAVE_SETREUID */
7812#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007813 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007814#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007815#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007816 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007817#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007818#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007819 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007820#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00007821#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007822 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00007823#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007824#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007825 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007826#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007827#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007828 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007829#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007830#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007831 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007832#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007833#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00007834 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007835#endif /* HAVE_WAIT3 */
7836#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00007837 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007838#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007839#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007840 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007841#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007842#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007843 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007844#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007845#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007846 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007847#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007848#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007849 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007850#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007851#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007852 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007853#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007854#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007855 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007856#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7858 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7859 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7860 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7861 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7862 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7863 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7864 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7865 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7866 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7867 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007868#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00007869 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007870#endif
7871#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007873#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007874#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00007875 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007876#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007877#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00007878 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7879 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7880 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007881#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007882#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00007883 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007884#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007885#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007886 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007887#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007888#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007889 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007890#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007891 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007892#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00007893 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007894#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007895#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007896 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007897#endif
7898#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007899 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007900#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007901#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007902#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00007903 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007904#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007905#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00007906 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007907#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007908#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00007909 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007910#endif /* WIFSTOPPED */
7911#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00007912 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007913#endif /* WIFSIGNALED */
7914#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00007915 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007916#endif /* WIFEXITED */
7917#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00007918 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007919#endif /* WEXITSTATUS */
7920#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007921 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007922#endif /* WTERMSIG */
7923#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007924 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007925#endif /* WSTOPSIG */
7926#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007927#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007928 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007929#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007930#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007931 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007932#endif
Fred Drakec9680921999-12-13 16:37:25 +00007933#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007935#endif
7936#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007937 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007938#endif
7939#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007940 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007941#endif
7942#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007943 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007944#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007945 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007946#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007947 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00007948 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +00007949 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00007950#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007951#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00007952 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007953#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007954 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007955 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007956 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007957 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007958 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007959 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007960#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007961 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007962#endif
7963#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007964 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007965#endif
7966#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007967 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007968#endif
7969#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007970 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007971#endif
7972
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007974};
7975
7976
Barry Warsaw4a342091996-12-19 23:50:02 +00007977static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007978ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007979{
Victor Stinner8c62be82010-05-06 00:08:46 +00007980 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007981}
7982
Guido van Rossumd48f2521997-12-05 22:19:34 +00007983#if defined(PYOS_OS2)
7984/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007985static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007986{
7987 APIRET rc;
7988 ULONG values[QSV_MAX+1];
7989 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007990 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007991
7992 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007993 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007994 Py_END_ALLOW_THREADS
7995
7996 if (rc != NO_ERROR) {
7997 os2_error(rc);
7998 return -1;
7999 }
8000
Fred Drake4d1e64b2002-04-15 19:40:07 +00008001 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8002 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8003 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8004 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8005 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8006 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8007 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008008
8009 switch (values[QSV_VERSION_MINOR]) {
8010 case 0: ver = "2.00"; break;
8011 case 10: ver = "2.10"; break;
8012 case 11: ver = "2.11"; break;
8013 case 30: ver = "3.00"; break;
8014 case 40: ver = "4.00"; break;
8015 case 50: ver = "5.00"; break;
8016 default:
Tim Peters885d4572001-11-28 20:27:42 +00008017 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00008019 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008020 ver = &tmp[0];
8021 }
8022
8023 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008024 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008025 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008026
8027 /* Add Indicator of Which Drive was Used to Boot the System */
8028 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8029 tmp[1] = ':';
8030 tmp[2] = '\0';
8031
Fred Drake4d1e64b2002-04-15 19:40:07 +00008032 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008033}
8034#endif
8035
Barry Warsaw4a342091996-12-19 23:50:02 +00008036static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008037all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008038{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008039#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008040 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008041#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008042#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008043 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008044#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008045#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008046 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008047#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008048#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008049 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008050#endif
Fred Drakec9680921999-12-13 16:37:25 +00008051#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008052 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00008053#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008054#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008055 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008056#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008057#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008058 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008059#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008060#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00008061 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008062#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008063#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00008064 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008065#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008066#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008067 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008068#endif
8069#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008070 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008071#endif
8072#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00008073 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008074#endif
8075#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00008076 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008077#endif
8078#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008079 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008080#endif
8081#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00008082 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008083#endif
8084#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008085 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008086#endif
8087#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008088 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008089#endif
8090#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008091 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008092#endif
8093#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008094 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008095#endif
8096#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008097 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008098#endif
8099#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00008100 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008101#endif
8102#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008103 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008104#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008105#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008106 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008107#endif
8108#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00008109 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008110#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008111#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008112 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008113#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008114#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008115 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008116#endif
8117#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008118 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008119#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008120
Tim Peters5aa91602002-01-30 05:46:57 +00008121/* MS Windows */
8122#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008123 /* Don't inherit in child processes. */
8124 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008125#endif
8126#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00008127 /* Optimize for short life (keep in memory). */
8128 /* MS forgot to define this one with a non-underscore form too. */
8129 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008130#endif
8131#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008132 /* Automatically delete when last handle is closed. */
8133 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008134#endif
8135#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008136 /* Optimize for random access. */
8137 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008138#endif
8139#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008140 /* Optimize for sequential access. */
8141 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008142#endif
8143
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008144/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008145#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008146 /* Send a SIGIO signal whenever input or output
8147 becomes available on file descriptor */
8148 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008149#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008150#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008151 /* Direct disk access. */
8152 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008153#endif
8154#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008155 /* Must be a directory. */
8156 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008157#endif
8158#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008159 /* Do not follow links. */
8160 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008161#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008162#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008163 /* Do not update the access time. */
8164 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008165#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008166
Victor Stinner8c62be82010-05-06 00:08:46 +00008167 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008168#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008169 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008170#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008171#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008172 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008173#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008174#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008175 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008176#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008177#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008178 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008179#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008180#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008181 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008182#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008183#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008184 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008185#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008186#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008187 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008188#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008189#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008190 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008191#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008192#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008193 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008194#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008195#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008196 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008197#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008198#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008199 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008200#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008201#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008202 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008203#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008204#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008205 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008206#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008207#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008208 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008209#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008210#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008211 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008212#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008213#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008214 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008215#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008216#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008217 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008218#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008219
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008220 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008221#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008222 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008223#endif /* ST_RDONLY */
8224#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008225 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008226#endif /* ST_NOSUID */
8227
Guido van Rossum246bc171999-02-01 23:54:31 +00008228#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008229#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008230 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8231 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8232 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8233 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8234 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8235 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8236 if (ins(d, "P_PM", (long)P_PM)) return -1;
8237 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8238 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8239 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8240 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8241 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8242 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8243 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8244 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8245 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8246 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8247 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8248 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8249 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008250#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008251 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8252 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8253 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8254 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8255 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008256#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008257#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008258
Guido van Rossumd48f2521997-12-05 22:19:34 +00008259#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008260 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008261#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008262 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008263}
8264
8265
Tim Peters5aa91602002-01-30 05:46:57 +00008266#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008267#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008268#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008269
8270#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008271#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008272#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008273
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008274#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008275#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008276#define MODNAME "posix"
8277#endif
8278
Martin v. Löwis1a214512008-06-11 05:26:20 +00008279static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008280 PyModuleDef_HEAD_INIT,
8281 MODNAME,
8282 posix__doc__,
8283 -1,
8284 posix_methods,
8285 NULL,
8286 NULL,
8287 NULL,
8288 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008289};
8290
8291
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008292PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008293INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008294{
Victor Stinner8c62be82010-05-06 00:08:46 +00008295 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008296
Victor Stinner8c62be82010-05-06 00:08:46 +00008297 m = PyModule_Create(&posixmodule);
8298 if (m == NULL)
8299 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008300
Victor Stinner8c62be82010-05-06 00:08:46 +00008301 /* Initialize environ dictionary */
8302 v = convertenviron();
8303 Py_XINCREF(v);
8304 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8305 return NULL;
8306 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008307
Victor Stinner8c62be82010-05-06 00:08:46 +00008308 if (all_ins(m))
8309 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008310
Victor Stinner8c62be82010-05-06 00:08:46 +00008311 if (setup_confname_tables(m))
8312 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008313
Victor Stinner8c62be82010-05-06 00:08:46 +00008314 Py_INCREF(PyExc_OSError);
8315 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008316
Guido van Rossumb3d39562000-01-31 18:41:26 +00008317#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008318 if (posix_putenv_garbage == NULL)
8319 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008320#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008321
Victor Stinner8c62be82010-05-06 00:08:46 +00008322 if (!initialized) {
8323 stat_result_desc.name = MODNAME ".stat_result";
8324 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8325 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8326 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8327 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8328 structseq_new = StatResultType.tp_new;
8329 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008330
Victor Stinner8c62be82010-05-06 00:08:46 +00008331 statvfs_result_desc.name = MODNAME ".statvfs_result";
8332 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008333#ifdef NEED_TICKS_PER_SECOND
8334# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008335 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008336# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008337 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008338# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008339 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008340# endif
8341#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008342 }
8343 Py_INCREF((PyObject*) &StatResultType);
8344 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8345 Py_INCREF((PyObject*) &StatVFSResultType);
8346 PyModule_AddObject(m, "statvfs_result",
8347 (PyObject*) &StatVFSResultType);
8348 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008349
8350#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008351 /*
8352 * Step 2 of weak-linking support on Mac OS X.
8353 *
8354 * The code below removes functions that are not available on the
8355 * currently active platform.
8356 *
8357 * This block allow one to use a python binary that was build on
8358 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8359 * OSX 10.4.
8360 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008361#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008362 if (fstatvfs == NULL) {
8363 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8364 return NULL;
8365 }
8366 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008367#endif /* HAVE_FSTATVFS */
8368
8369#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008370 if (statvfs == NULL) {
8371 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8372 return NULL;
8373 }
8374 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008375#endif /* HAVE_STATVFS */
8376
8377# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008378 if (lchown == NULL) {
8379 if (PyObject_DelAttrString(m, "lchown") == -1) {
8380 return NULL;
8381 }
8382 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008383#endif /* HAVE_LCHOWN */
8384
8385
8386#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008387 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008388
Guido van Rossumb6775db1994-08-01 11:34:53 +00008389}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008390
8391#ifdef __cplusplus
8392}
8393#endif