blob: 82bbd91964220fcc799bb8e8785b4a114117ff7c [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Thomas Wouters477c8d52006-05-27 19:21:47 +000016#ifdef __APPLE__
17 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000018 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000019 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
31#include "structseq.h"
32
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000048#if defined(PYOS_OS2)
49#define INCL_DOS
50#define INCL_DOSERRORS
51#define INCL_DOSPROCESS
52#define INCL_NOPMAPI
53#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000054#if defined(PYCC_GCC)
55#include <ctype.h>
56#include <io.h>
57#include <stdio.h>
58#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000059#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000060#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000061#endif
62
Thomas Wouters0e3f5912006-08-11 14:57:12 +000063#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000064#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000065#endif /* HAVE_SYS_TYPES_H */
66
67#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000069#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070
Guido van Rossum36bc6801995-06-14 22:54:23 +000071#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000072#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000073#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000074
Thomas Wouters0e3f5912006-08-11 14:57:12 +000075#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000076#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000077#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000078
Guido van Rossumb6775db1994-08-01 11:34:53 +000079#ifdef HAVE_FCNTL_H
80#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000081#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000082
Guido van Rossuma6535fd2001-10-18 19:44:10 +000083#ifdef HAVE_GRP_H
84#include <grp.h>
85#endif
86
Barry Warsaw5676bd12003-01-07 20:57:09 +000087#ifdef HAVE_SYSEXITS_H
88#include <sysexits.h>
89#endif /* HAVE_SYSEXITS_H */
90
Anthony Baxter8a560de2004-10-13 15:30:56 +000091#ifdef HAVE_SYS_LOADAVG_H
92#include <sys/loadavg.h>
93#endif
94
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000095#ifdef HAVE_LANGINFO_H
96#include <langinfo.h>
97#endif
98
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000100/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#include <process.h>
103#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000104#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#define HAVE_GETCWD 1
106#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000107#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#if defined(__OS2__)
109#define HAVE_EXECV 1
110#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#include <process.h>
113#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000114#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000115#define HAVE_EXECV 1
116#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_OPENDIR 1
118#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000119#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#define HAVE_WAIT 1
121#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000122#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000123#define HAVE_GETCWD 1
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000124#define HAVE_GETPPID 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000125#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000126#define HAVE_EXECV 1
127#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000128#define HAVE_SYSTEM 1
129#define HAVE_CWAIT 1
130#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000131#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000132#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000133#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
134/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000135#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136/* Unix functions that the configure script doesn't check for */
137#define HAVE_EXECV 1
138#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000139#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000140#define HAVE_FORK1 1
141#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142#define HAVE_GETCWD 1
143#define HAVE_GETEGID 1
144#define HAVE_GETEUID 1
145#define HAVE_GETGID 1
146#define HAVE_GETPPID 1
147#define HAVE_GETUID 1
148#define HAVE_KILL 1
149#define HAVE_OPENDIR 1
150#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000151#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000152#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000153#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000154#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#endif /* _MSC_VER */
156#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000157#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000158#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000159
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000161
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000162#if defined(__sgi)&&_COMPILER_VERSION>=700
163/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
164 (default) */
165extern char *ctermid_r(char *);
166#endif
167
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000168#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000169#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000170extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000171#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000172#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000173extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000174#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000175extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000177#endif
178#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000179extern int chdir(char *);
180extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000181#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000182extern int chdir(const char *);
183extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000184#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000185#ifdef __BORLANDC__
186extern int chmod(const char *, int);
187#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000188extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000189#endif
Christian Heimes4e30a842007-11-30 22:12:06 +0000190/*#ifdef HAVE_FCHMOD
191extern int fchmod(int, mode_t);
192#endif*/
193/*#ifdef HAVE_LCHMOD
194extern int lchmod(const char *, mode_t);
195#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000196extern int chown(const char *, uid_t, gid_t);
197extern char *getcwd(char *, int);
198extern char *strerror(int);
199extern int link(const char *, const char *);
200extern int rename(const char *, const char *);
201extern int stat(const char *, struct stat *);
202extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000203#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000205#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000206#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000207extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000208#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000210
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000211#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000212
Guido van Rossumb6775db1994-08-01 11:34:53 +0000213#ifdef HAVE_UTIME_H
214#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000215#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000217#ifdef HAVE_SYS_UTIME_H
218#include <sys/utime.h>
219#define HAVE_UTIME_H /* pretend we do for the rest of this file */
220#endif /* HAVE_SYS_UTIME_H */
221
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#ifdef HAVE_SYS_TIMES_H
223#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000224#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225
226#ifdef HAVE_SYS_PARAM_H
227#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000228#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229
230#ifdef HAVE_SYS_UTSNAME_H
231#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000232#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000234#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000236#define NAMLEN(dirent) strlen((dirent)->d_name)
237#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000238#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000239#include <direct.h>
240#define NAMLEN(dirent) strlen((dirent)->d_name)
241#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000243#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000244#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000245#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000247#endif
248#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000250#endif
251#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000253#endif
254#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000256#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000257#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000259#endif
260#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000262#endif
263#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000265#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000266#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000267#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000268#endif
269#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000270#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000271#endif
272#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000273#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000274#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000275#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000276#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000278#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000279#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280
Guido van Rossumd48f2521997-12-05 22:19:34 +0000281#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000283#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284
Tim Petersbc2e10e2002-03-03 23:17:02 +0000285#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000286#if defined(PATH_MAX) && PATH_MAX > 1024
287#define MAXPATHLEN PATH_MAX
288#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000289#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000290#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000291#endif /* MAXPATHLEN */
292
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000293#ifdef UNION_WAIT
294/* Emulate some macros on systems that have a union instead of macros */
295
296#ifndef WIFEXITED
297#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
298#endif
299
300#ifndef WEXITSTATUS
301#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
302#endif
303
304#ifndef WTERMSIG
305#define WTERMSIG(u_wait) ((u_wait).w_termsig)
306#endif
307
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000308#define WAIT_TYPE union wait
309#define WAIT_STATUS_INT(s) (s.w_status)
310
311#else /* !UNION_WAIT */
312#define WAIT_TYPE int
313#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000314#endif /* UNION_WAIT */
315
Greg Wardb48bc172000-03-01 21:51:56 +0000316/* Don't use the "_r" form if we don't need it (also, won't have a
317 prototype for it, at least on Solaris -- maybe others as well?). */
318#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
319#define USE_CTERMID_R
320#endif
321
Fred Drake699f3522000-06-29 21:12:41 +0000322/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000323#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000324#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +0000325# define STAT win32_stat
326# define FSTAT win32_fstat
327# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000328#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000329# define STAT stat
330# define FSTAT fstat
331# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000332#endif
333
Tim Peters11b23062003-04-23 02:39:17 +0000334#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000335#include <sys/mkdev.h>
336#else
337#if defined(MAJOR_IN_SYSMACROS)
338#include <sys/sysmacros.h>
339#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000340#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
341#include <sys/mkdev.h>
342#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000343#endif
Fred Drake699f3522000-06-29 21:12:41 +0000344
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000345#if defined _MSC_VER && _MSC_VER >= 1400
346/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
347 * valid and throw an assertion if it isn't.
348 * Normally, an invalid fd is likely to be a C program error and therefore
349 * an assertion can be useful, but it does contradict the POSIX standard
350 * which for write(2) states:
351 * "Otherwise, -1 shall be returned and errno set to indicate the error."
352 * "[EBADF] The fildes argument is not a valid file descriptor open for
353 * writing."
354 * Furthermore, python allows the user to enter any old integer
355 * as a fd and should merely raise a python exception on error.
356 * The Microsoft CRT doesn't provide an official way to check for the
357 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinner8c62be82010-05-06 00:08:46 +0000358 * by using the exported __pinfo data member and knowledge of the
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000359 * internal structures involved.
360 * The structures below must be updated for each version of visual studio
361 * according to the file internal.h in the CRT source, until MS comes
362 * up with a less hacky way to do this.
363 * (all of this is to avoid globally modifying the CRT behaviour using
364 * _set_invalid_parameter_handler() and _CrtSetReportMode())
365 */
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000366/* The actual size of the structure is determined at runtime.
367 * Only the first items must be present.
368 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000369typedef struct {
Victor Stinner8c62be82010-05-06 00:08:46 +0000370 intptr_t osfhnd;
371 char osfile;
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000372} my_ioinfo;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000373
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000374extern __declspec(dllimport) char * __pioinfo[];
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000375#define IOINFO_L2E 5
376#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
377#define IOINFO_ARRAYS 64
378#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
379#define FOPEN 0x01
380#define _NO_CONSOLE_FILENO (intptr_t)-2
381
382/* This function emulates what the windows CRT does to validate file handles */
383int
384_PyVerify_fd(int fd)
385{
Victor Stinner8c62be82010-05-06 00:08:46 +0000386 const int i1 = fd >> IOINFO_L2E;
387 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000388
Antoine Pitrou22e41552010-08-15 18:07:50 +0000389 static size_t sizeof_ioinfo = 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000390
Victor Stinner8c62be82010-05-06 00:08:46 +0000391 /* Determine the actual size of the ioinfo structure,
392 * as used by the CRT loaded in memory
393 */
394 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
395 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
396 }
397 if (sizeof_ioinfo == 0) {
398 /* This should not happen... */
399 goto fail;
400 }
401
402 /* See that it isn't a special CLEAR fileno */
403 if (fd != _NO_CONSOLE_FILENO) {
404 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
405 * we check pointer validity and other info
406 */
407 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
408 /* finally, check that the file is open */
409 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
410 if (info->osfile & FOPEN) {
411 return 1;
412 }
413 }
414 }
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000415 fail:
Victor Stinner8c62be82010-05-06 00:08:46 +0000416 errno = EBADF;
417 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000418}
419
420/* the special case of checking dup2. The target fd must be in a sensible range */
421static int
422_PyVerify_fd_dup2(int fd1, int fd2)
423{
Victor Stinner8c62be82010-05-06 00:08:46 +0000424 if (!_PyVerify_fd(fd1))
425 return 0;
426 if (fd2 == _NO_CONSOLE_FILENO)
427 return 0;
428 if ((unsigned)fd2 < _NHANDLE_)
429 return 1;
430 else
431 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +0000432}
433#else
434/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
435#define _PyVerify_fd_dup2(A, B) (1)
436#endif
437
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000438/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000439#ifdef WITH_NEXT_FRAMEWORK
440/* On Darwin/MacOSX a shared library or framework has no access to
441** environ directly, we must obtain it with _NSGetEnviron().
442*/
443#include <crt_externs.h>
444static char **environ;
445#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000446extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000447#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000448
Barry Warsaw53699e91996-12-10 23:23:01 +0000449static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000450convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000451{
Victor Stinner8c62be82010-05-06 00:08:46 +0000452 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000453#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000454 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000455#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000456 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +0000457#endif
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000458#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +0000459 APIRET rc;
460 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
461#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +0000462
Victor Stinner8c62be82010-05-06 00:08:46 +0000463 d = PyDict_New();
464 if (d == NULL)
465 return NULL;
466#ifdef WITH_NEXT_FRAMEWORK
467 if (environ == NULL)
468 environ = *_NSGetEnviron();
469#endif
470#ifdef MS_WINDOWS
471 /* _wenviron must be initialized in this way if the program is started
472 through main() instead of wmain(). */
473 _wgetenv(L"");
474 if (_wenviron == NULL)
475 return d;
476 /* This part ignores errors */
477 for (e = _wenviron; *e != NULL; e++) {
478 PyObject *k;
479 PyObject *v;
480 wchar_t *p = wcschr(*e, L'=');
481 if (p == NULL)
482 continue;
483 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
484 if (k == NULL) {
485 PyErr_Clear();
486 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000487 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000488 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
489 if (v == NULL) {
490 PyErr_Clear();
491 Py_DECREF(k);
492 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000493 }
Victor Stinner8c62be82010-05-06 00:08:46 +0000494 if (PyDict_GetItem(d, k) == NULL) {
495 if (PyDict_SetItem(d, k, v) != 0)
496 PyErr_Clear();
497 }
498 Py_DECREF(k);
499 Py_DECREF(v);
500 }
501#else
502 if (environ == NULL)
503 return d;
504 /* This part ignores errors */
505 for (e = environ; *e != NULL; e++) {
506 PyObject *k;
507 PyObject *v;
508 char *p = strchr(*e, '=');
509 if (p == NULL)
510 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +0000511 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +0000512 if (k == NULL) {
513 PyErr_Clear();
514 continue;
515 }
Victor Stinner84ae1182010-05-06 22:05:07 +0000516 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +0000517 if (v == NULL) {
518 PyErr_Clear();
519 Py_DECREF(k);
520 continue;
521 }
522 if (PyDict_GetItem(d, k) == NULL) {
523 if (PyDict_SetItem(d, k, v) != 0)
524 PyErr_Clear();
525 }
526 Py_DECREF(k);
527 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000528 }
529#endif
Victor Stinner8c62be82010-05-06 00:08:46 +0000530#if defined(PYOS_OS2)
531 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
532 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
533 PyObject *v = PyBytes_FromString(buffer);
534 PyDict_SetItemString(d, "BEGINLIBPATH", v);
535 Py_DECREF(v);
536 }
537 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
538 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
539 PyObject *v = PyBytes_FromString(buffer);
540 PyDict_SetItemString(d, "ENDLIBPATH", v);
541 Py_DECREF(v);
542 }
543#endif
544 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000545}
546
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000547/* Set a POSIX-specific error from errno, and return NULL */
548
Barry Warsawd58d7641998-07-23 16:14:40 +0000549static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000550posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000551{
Victor Stinner8c62be82010-05-06 00:08:46 +0000552 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000553}
Barry Warsawd58d7641998-07-23 16:14:40 +0000554static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000555posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000556{
Victor Stinner8c62be82010-05-06 00:08:46 +0000557 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000558}
559
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000560#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000561static PyObject *
562posix_error_with_unicode_filename(Py_UNICODE* name)
563{
Victor Stinner8c62be82010-05-06 00:08:46 +0000564 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000565}
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000566#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000567
568
Mark Hammondef8b6542001-05-13 08:04:26 +0000569static PyObject *
Martin v. Löwis011e8422009-05-05 04:43:17 +0000570posix_error_with_allocated_filename(PyObject* name)
Mark Hammondef8b6542001-05-13 08:04:26 +0000571{
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000572 PyObject *name_str, *rc;
573 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
574 PyBytes_GET_SIZE(name));
Victor Stinner8c62be82010-05-06 00:08:46 +0000575 Py_DECREF(name);
Victor Stinner77ccd6d2010-05-08 00:36:42 +0000576 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
577 name_str);
578 Py_XDECREF(name_str);
Victor Stinner8c62be82010-05-06 00:08:46 +0000579 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000580}
581
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000582#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000583static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +0000584win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000585{
Victor Stinner8c62be82010-05-06 00:08:46 +0000586 /* XXX We should pass the function name along in the future.
587 (winreg.c also wants to pass the function name.)
588 This would however require an additional param to the
589 Windows error object, which is non-trivial.
590 */
591 errno = GetLastError();
592 if (filename)
593 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
594 else
595 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000596}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000597
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000598static PyObject *
599win32_error_unicode(char* function, Py_UNICODE* filename)
600{
Victor Stinner8c62be82010-05-06 00:08:46 +0000601 /* XXX - see win32_error for comments on 'function' */
602 errno = GetLastError();
603 if (filename)
604 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
605 else
606 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000607}
608
Thomas Wouters477c8d52006-05-27 19:21:47 +0000609static int
Hirokazu Yamamotod7e4c082008-08-17 09:30:15 +0000610convert_to_unicode(PyObject **param)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000611{
Victor Stinner8c62be82010-05-06 00:08:46 +0000612 if (PyUnicode_CheckExact(*param))
613 Py_INCREF(*param);
614 else if (PyUnicode_Check(*param))
615 /* For a Unicode subtype that's not a Unicode object,
616 return a true Unicode object with the same data. */
617 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
618 PyUnicode_GET_SIZE(*param));
619 else
620 *param = PyUnicode_FromEncodedObject(*param,
621 Py_FileSystemDefaultEncoding,
622 "strict");
623 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000624}
625
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000626#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000627
Guido van Rossumd48f2521997-12-05 22:19:34 +0000628#if defined(PYOS_OS2)
629/**********************************************************************
630 * Helper Function to Trim and Format OS/2 Messages
631 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000632static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000633os2_formatmsg(char *msgbuf, int msglen, char *reason)
634{
635 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
636
637 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
638 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
639
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000640 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000641 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
642 }
643
644 /* Add Optional Reason Text */
645 if (reason) {
646 strcat(msgbuf, " : ");
647 strcat(msgbuf, reason);
648 }
649}
650
651/**********************************************************************
652 * Decode an OS/2 Operating System Error Code
653 *
654 * A convenience function to lookup an OS/2 error code and return a
655 * text message we can use to raise a Python exception.
656 *
657 * Notes:
658 * The messages for errors returned from the OS/2 kernel reside in
659 * the file OSO001.MSG in the \OS2 directory hierarchy.
660 *
661 **********************************************************************/
Victor Stinner8c62be82010-05-06 00:08:46 +0000662static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000663os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
664{
665 APIRET rc;
666 ULONG msglen;
667
668 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
669 Py_BEGIN_ALLOW_THREADS
670 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
671 errorcode, "oso001.msg", &msglen);
672 Py_END_ALLOW_THREADS
673
674 if (rc == NO_ERROR)
675 os2_formatmsg(msgbuf, msglen, reason);
676 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000677 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinner8c62be82010-05-06 00:08:46 +0000678 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000679
680 return msgbuf;
681}
682
683/* Set an OS/2-specific error and return NULL. OS/2 kernel
684 errors are not in a global variable e.g. 'errno' nor are
685 they congruent with posix error numbers. */
686
Victor Stinner8c62be82010-05-06 00:08:46 +0000687static PyObject *
688os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000689{
690 char text[1024];
691 PyObject *v;
692
693 os2_strerror(text, sizeof(text), code, "");
694
695 v = Py_BuildValue("(is)", code, text);
696 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000697 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000698 Py_DECREF(v);
699 }
700 return NULL; /* Signal to Python that an Exception is Pending */
701}
702
703#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000704
705/* POSIX generic methods */
706
Barry Warsaw53699e91996-12-10 23:23:01 +0000707static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000708posix_fildes(PyObject *fdobj, int (*func)(int))
709{
Victor Stinner8c62be82010-05-06 00:08:46 +0000710 int fd;
711 int res;
712 fd = PyObject_AsFileDescriptor(fdobj);
713 if (fd < 0)
714 return NULL;
715 if (!_PyVerify_fd(fd))
716 return posix_error();
717 Py_BEGIN_ALLOW_THREADS
718 res = (*func)(fd);
719 Py_END_ALLOW_THREADS
720 if (res < 0)
721 return posix_error();
722 Py_INCREF(Py_None);
723 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000724}
Guido van Rossum21142a01999-01-08 21:05:37 +0000725
726static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000727posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000728{
Victor Stinner8c62be82010-05-06 00:08:46 +0000729 PyObject *opath1 = NULL;
730 char *path1;
731 int res;
732 if (!PyArg_ParseTuple(args, format,
733 PyUnicode_FSConverter, &opath1))
734 return NULL;
735 path1 = PyBytes_AsString(opath1);
736 Py_BEGIN_ALLOW_THREADS
737 res = (*func)(path1);
738 Py_END_ALLOW_THREADS
739 if (res < 0)
740 return posix_error_with_allocated_filename(opath1);
741 Py_DECREF(opath1);
742 Py_INCREF(Py_None);
743 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000744}
745
Barry Warsaw53699e91996-12-10 23:23:01 +0000746static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000747posix_2str(PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +0000748 char *format,
749 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000750{
Victor Stinner8c62be82010-05-06 00:08:46 +0000751 PyObject *opath1 = NULL, *opath2 = NULL;
752 char *path1, *path2;
753 int res;
754 if (!PyArg_ParseTuple(args, format,
755 PyUnicode_FSConverter, &opath1,
756 PyUnicode_FSConverter, &opath2)) {
757 return NULL;
758 }
759 path1 = PyBytes_AsString(opath1);
760 path2 = PyBytes_AsString(opath2);
761 Py_BEGIN_ALLOW_THREADS
762 res = (*func)(path1, path2);
763 Py_END_ALLOW_THREADS
764 Py_DECREF(opath1);
765 Py_DECREF(opath2);
766 if (res != 0)
767 /* XXX how to report both path1 and path2??? */
768 return posix_error();
769 Py_INCREF(Py_None);
770 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000771}
772
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +0000773#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +0000774static PyObject*
Victor Stinner8c62be82010-05-06 00:08:46 +0000775win32_1str(PyObject* args, char* func,
776 char* format, BOOL (__stdcall *funcA)(LPCSTR),
777 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000778{
Victor Stinner8c62be82010-05-06 00:08:46 +0000779 PyObject *uni;
780 char *ansi;
781 BOOL result;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +0000782
Victor Stinner8c62be82010-05-06 00:08:46 +0000783 if (!PyArg_ParseTuple(args, wformat, &uni))
784 PyErr_Clear();
785 else {
786 Py_BEGIN_ALLOW_THREADS
787 result = funcW(PyUnicode_AsUnicode(uni));
788 Py_END_ALLOW_THREADS
789 if (!result)
790 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
791 Py_INCREF(Py_None);
792 return Py_None;
793 }
794 if (!PyArg_ParseTuple(args, format, &ansi))
795 return NULL;
796 Py_BEGIN_ALLOW_THREADS
797 result = funcA(ansi);
798 Py_END_ALLOW_THREADS
799 if (!result)
800 return win32_error(func, ansi);
801 Py_INCREF(Py_None);
802 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000803
804}
805
806/* This is a reimplementation of the C library's chdir function,
807 but one that produces Win32 errors instead of DOS error codes.
808 chdir is essentially a wrapper around SetCurrentDirectory; however,
809 it also needs to set "magic" environment variables indicating
810 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000811static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000812win32_chdir(LPCSTR path)
813{
Victor Stinner8c62be82010-05-06 00:08:46 +0000814 char new_path[MAX_PATH+1];
815 int result;
816 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000817
Victor Stinner8c62be82010-05-06 00:08:46 +0000818 if(!SetCurrentDirectoryA(path))
819 return FALSE;
820 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
821 if (!result)
822 return FALSE;
823 /* In the ANSI API, there should not be any paths longer
824 than MAX_PATH. */
825 assert(result <= MAX_PATH+1);
826 if (strncmp(new_path, "\\\\", 2) == 0 ||
827 strncmp(new_path, "//", 2) == 0)
828 /* UNC path, nothing to do. */
829 return TRUE;
830 env[1] = new_path[0];
831 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000832}
833
834/* The Unicode version differs from the ANSI version
835 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +0000836static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +0000837win32_wchdir(LPCWSTR path)
838{
Victor Stinner8c62be82010-05-06 00:08:46 +0000839 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
840 int result;
841 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +0000842
Victor Stinner8c62be82010-05-06 00:08:46 +0000843 if(!SetCurrentDirectoryW(path))
844 return FALSE;
845 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
846 if (!result)
847 return FALSE;
848 if (result > MAX_PATH+1) {
849 new_path = malloc(result * sizeof(wchar_t));
850 if (!new_path) {
851 SetLastError(ERROR_OUTOFMEMORY);
852 return FALSE;
853 }
854 result = GetCurrentDirectoryW(result, new_path);
855 if (!result) {
856 free(new_path);
857 return FALSE;
858 }
859 }
860 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
861 wcsncmp(new_path, L"//", 2) == 0)
862 /* UNC path, nothing to do. */
863 return TRUE;
864 env[1] = new_path[0];
865 result = SetEnvironmentVariableW(env, new_path);
866 if (new_path != _new_path)
867 free(new_path);
868 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000869}
870#endif
871
Martin v. Löwis14694662006-02-03 12:54:16 +0000872#ifdef MS_WINDOWS
873/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
874 - time stamps are restricted to second resolution
875 - file modification times suffer from forth-and-back conversions between
876 UTC and local time
877 Therefore, we implement our own stat, based on the Win32 API directly.
878*/
Victor Stinner8c62be82010-05-06 00:08:46 +0000879#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000880
881struct win32_stat{
882 int st_dev;
883 __int64 st_ino;
884 unsigned short st_mode;
885 int st_nlink;
886 int st_uid;
887 int st_gid;
888 int st_rdev;
889 __int64 st_size;
890 int st_atime;
891 int st_atime_nsec;
892 int st_mtime;
893 int st_mtime_nsec;
894 int st_ctime;
895 int st_ctime_nsec;
896};
897
898static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
899
900static void
901FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
902{
Victor Stinner8c62be82010-05-06 00:08:46 +0000903 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
904 /* Cannot simply cast and dereference in_ptr,
905 since it might not be aligned properly */
906 __int64 in;
907 memcpy(&in, in_ptr, sizeof(in));
908 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
909 /* XXX Win32 supports time stamps past 2038; we currently don't */
910 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
Martin v. Löwis14694662006-02-03 12:54:16 +0000911}
912
Thomas Wouters477c8d52006-05-27 19:21:47 +0000913static void
914time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
915{
Victor Stinner8c62be82010-05-06 00:08:46 +0000916 /* XXX endianness */
917 __int64 out;
918 out = time_in + secs_between_epochs;
919 out = out * 10000000 + nsec_in / 100;
920 memcpy(out_ptr, &out, sizeof(out));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000921}
922
Martin v. Löwis14694662006-02-03 12:54:16 +0000923/* Below, we *know* that ugo+r is 0444 */
924#if _S_IREAD != 0400
925#error Unsupported C library
926#endif
927static int
928attributes_to_mode(DWORD attr)
929{
Victor Stinner8c62be82010-05-06 00:08:46 +0000930 int m = 0;
931 if (attr & FILE_ATTRIBUTE_DIRECTORY)
932 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
933 else
934 m |= _S_IFREG;
935 if (attr & FILE_ATTRIBUTE_READONLY)
936 m |= 0444;
937 else
938 m |= 0666;
939 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +0000940}
941
942static int
943attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
944{
Victor Stinner8c62be82010-05-06 00:08:46 +0000945 memset(result, 0, sizeof(*result));
946 result->st_mode = attributes_to_mode(info->dwFileAttributes);
947 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
948 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
949 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
950 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +0000951
Victor Stinner8c62be82010-05-06 00:08:46 +0000952 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +0000953}
954
Guido van Rossumd8faa362007-04-27 19:54:29 +0000955static BOOL
956attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
957{
Victor Stinner8c62be82010-05-06 00:08:46 +0000958 HANDLE hFindFile;
959 WIN32_FIND_DATAA FileData;
960 hFindFile = FindFirstFileA(pszFile, &FileData);
961 if (hFindFile == INVALID_HANDLE_VALUE)
962 return FALSE;
963 FindClose(hFindFile);
964 pfad->dwFileAttributes = FileData.dwFileAttributes;
965 pfad->ftCreationTime = FileData.ftCreationTime;
966 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
967 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
968 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
969 pfad->nFileSizeLow = FileData.nFileSizeLow;
970 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000971}
972
973static BOOL
974attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
975{
Victor Stinner8c62be82010-05-06 00:08:46 +0000976 HANDLE hFindFile;
977 WIN32_FIND_DATAW FileData;
978 hFindFile = FindFirstFileW(pszFile, &FileData);
979 if (hFindFile == INVALID_HANDLE_VALUE)
980 return FALSE;
981 FindClose(hFindFile);
982 pfad->dwFileAttributes = FileData.dwFileAttributes;
983 pfad->ftCreationTime = FileData.ftCreationTime;
984 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
985 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
986 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
987 pfad->nFileSizeLow = FileData.nFileSizeLow;
988 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +0000989}
990
Brian Curtind40e6f72010-07-08 21:39:08 +0000991/* About the following functions: win32_lstat, win32_lstat_w, win32_stat,
992 win32_stat_w
993
994 In Posix, stat automatically traverses symlinks and returns the stat
995 structure for the target. In Windows, the equivalent GetFileAttributes by
996 default does not traverse symlinks and instead returns attributes for
997 the symlink.
998
999 Therefore, win32_lstat will get the attributes traditionally, and
1000 win32_stat will first explicitly resolve the symlink target and then will
1001 call win32_lstat on that result.
1002
1003 The _w represent Unicode equivalents of the aformentioned ANSI functions. */
1004
1005static int
1006win32_lstat(const char* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001007{
Victor Stinner8c62be82010-05-06 00:08:46 +00001008 WIN32_FILE_ATTRIBUTE_DATA info;
1009 int code;
1010 char *dot;
Brian Curtind40e6f72010-07-08 21:39:08 +00001011 WIN32_FIND_DATAA find_data;
1012 HANDLE find_data_handle;
Victor Stinner8c62be82010-05-06 00:08:46 +00001013 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1014 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1015 /* Protocol violation: we explicitly clear errno, instead of
1016 setting it to a POSIX error. Callers should use GetLastError. */
1017 errno = 0;
1018 return -1;
1019 } else {
1020 /* Could not get attributes on open file. Fall back to
1021 reading the directory. */
1022 if (!attributes_from_dir(path, &info)) {
1023 /* Very strange. This should not fail now */
1024 errno = 0;
1025 return -1;
1026 }
1027 }
1028 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001029
Victor Stinner8c62be82010-05-06 00:08:46 +00001030 code = attribute_data_to_stat(&info, result);
1031 if (code != 0)
1032 return code;
Brian Curtind40e6f72010-07-08 21:39:08 +00001033
1034 /* Get WIN32_FIND_DATA structure for the path to determine if
1035 it is a symlink */
1036 if(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1037 find_data_handle = FindFirstFileA(path, &find_data);
1038 if(find_data_handle != INVALID_HANDLE_VALUE) {
1039 if(find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
1040 /* first clear the S_IFMT bits */
1041 result->st_mode ^= (result->st_mode & 0170000);
1042 /* now set the bits that make this a symlink */
1043 result->st_mode |= 0120000;
1044 }
1045 FindClose(find_data_handle);
1046 }
1047 }
1048
Victor Stinner8c62be82010-05-06 00:08:46 +00001049 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1050 dot = strrchr(path, '.');
1051 if (dot) {
Brian Curtind40e6f72010-07-08 21:39:08 +00001052 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1053 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00001054 result->st_mode |= 0111;
1055 }
1056 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001057}
1058
Victor Stinner8c62be82010-05-06 00:08:46 +00001059static int
Brian Curtind40e6f72010-07-08 21:39:08 +00001060win32_lstat_w(const wchar_t* path, struct win32_stat *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001061{
Victor Stinner8c62be82010-05-06 00:08:46 +00001062 int code;
1063 const wchar_t *dot;
1064 WIN32_FILE_ATTRIBUTE_DATA info;
Brian Curtind40e6f72010-07-08 21:39:08 +00001065 WIN32_FIND_DATAW find_data;
1066 HANDLE find_data_handle;
Victor Stinner8c62be82010-05-06 00:08:46 +00001067 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1068 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1069 /* Protocol violation: we explicitly clear errno, instead of
1070 setting it to a POSIX error. Callers should use GetLastError. */
1071 errno = 0;
1072 return -1;
1073 } else {
Brian Curtind40e6f72010-07-08 21:39:08 +00001074 /* Could not get attributes on open file. Fall back to reading
1075 the directory. */
1076 if (!attributes_from_dir_w(path, &info)) {
1077 /* Very strange. This should not fail now */
1078 errno = 0;
1079 return -1;
1080 }
1081 }
1082 }
1083 code = attribute_data_to_stat(&info, result);
1084 if (code < 0)
1085 return code;
1086
1087 /* Get WIN32_FIND_DATA structure for the path to determine if
1088 it is a symlink */
1089 if(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1090 find_data_handle = FindFirstFileW(path, &find_data);
1091 if(find_data_handle != INVALID_HANDLE_VALUE) {
1092 if(find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
1093 /* first clear the S_IFMT bits */
1094 result->st_mode ^= (result->st_mode & 0170000);
1095 /* now set the bits that make this a symlink */
1096 result->st_mode |= 0120000;
1097 }
1098 FindClose(find_data_handle);
1099 }
1100 }
1101
1102 /* Set IFEXEC if it is an .exe, .bat, ... */
1103 dot = wcsrchr(path, '.');
1104 if (dot) {
1105 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1106 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1107 result->st_mode |= 0111;
1108 }
1109 return code;
1110}
1111
1112/* Grab GetFinalPathNameByHandle dynamically from kernel32 */
1113static int has_GetFinalPathNameByHandle = 0;
1114static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD,
1115 DWORD);
1116static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD,
1117 DWORD);
1118static int
1119check_GetFinalPathNameByHandle()
1120{
1121 HINSTANCE hKernel32;
1122 /* only recheck */
1123 if (!has_GetFinalPathNameByHandle)
1124 {
1125 hKernel32 = GetModuleHandle("KERNEL32");
1126 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32,
1127 "GetFinalPathNameByHandleA");
1128 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32,
1129 "GetFinalPathNameByHandleW");
Brian Curtin74e45612010-07-09 15:58:59 +00001130 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA &&
1131 Py_GetFinalPathNameByHandleW;
Brian Curtind40e6f72010-07-08 21:39:08 +00001132 }
1133 return has_GetFinalPathNameByHandle;
1134}
1135
1136static int
1137win32_stat(const char* path, struct win32_stat *result)
1138{
1139 /* Traverse the symlink to the target using
1140 GetFinalPathNameByHandle()
1141 */
1142 int code;
1143 HANDLE hFile;
1144 int buf_size;
1145 char *target_path;
1146 int result_length;
1147 WIN32_FILE_ATTRIBUTE_DATA info;
1148
1149 if(!check_GetFinalPathNameByHandle()) {
1150 /* if the OS doesn't have GetFinalPathNameByHandle, it doesn't
1151 have symlinks, so just fall back to the traditional behavior
1152 found in lstat. */
1153 return win32_lstat(path, result);
1154 }
1155
1156 hFile = CreateFileA(
1157 path,
1158 0, /* desired access */
1159 0, /* share mode */
1160 NULL, /* security attributes */
1161 OPEN_EXISTING,
1162 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1163 FILE_FLAG_BACKUP_SEMANTICS,
1164 NULL);
1165
1166 if(hFile == INVALID_HANDLE_VALUE) {
1167 /* Either the target doesn't exist, or we don't have access to
1168 get a handle to it. If the former, we need to return an error.
1169 If the latter, we can use attributes_from_dir. */
1170 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1171 /* Protocol violation: we explicitly clear errno, instead of
1172 setting it to a POSIX error. Callers should use GetLastError. */
1173 errno = 0;
1174 return -1;
1175 } else {
1176 /* Could not get attributes on open file. Fall back to
1177 reading the directory. */
1178 if (!attributes_from_dir(path, &info)) {
1179 /* Very strange. This should not fail now */
1180 errno = 0;
1181 return -1;
1182 }
1183 }
1184 code = attribute_data_to_stat(&info, result);
1185 }
1186
1187 buf_size = Py_GetFinalPathNameByHandleA(hFile, 0, 0, VOLUME_NAME_DOS);
1188 if(!buf_size) return -1;
1189 target_path = (char *)malloc((buf_size+1)*sizeof(char));
1190 result_length = Py_GetFinalPathNameByHandleA(hFile, target_path,
1191 buf_size, VOLUME_NAME_DOS);
1192
1193 if(!result_length)
1194 return -1;
1195
1196 if(!CloseHandle(hFile))
1197 return -1;
1198
1199 target_path[result_length] = 0;
1200 code = win32_lstat(target_path, result);
1201 free(target_path);
1202
1203 return code;
1204}
1205
1206static int
1207win32_stat_w(const wchar_t* path, struct win32_stat *result)
1208{
1209 /* Traverse the symlink to the target using GetFinalPathNameByHandle() */
1210 int code;
1211 HANDLE hFile;
1212 int buf_size;
1213 wchar_t *target_path;
1214 int result_length;
1215 WIN32_FILE_ATTRIBUTE_DATA info;
1216
1217 if(!check_GetFinalPathNameByHandle()) {
1218 /* If the OS doesn't have GetFinalPathNameByHandle, it doesn't have
1219 symlinks, so just fall back to the traditional behavior found
1220 in lstat. */
1221 return win32_lstat_w(path, result);
1222 }
1223
1224 hFile = CreateFileW(
1225 path,
1226 0, /* desired access */
1227 0, /* share mode */
1228 NULL, /* security attributes */
1229 OPEN_EXISTING,
1230 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
1231 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1232 NULL);
Antoine Pitroub73caab2010-08-09 23:39:31 +00001233
Brian Curtind40e6f72010-07-08 21:39:08 +00001234 if(hFile == INVALID_HANDLE_VALUE) {
1235 /* Either the target doesn't exist, or we don't have access to
1236 get a handle to it. If the former, we need to return an error.
1237 If the latter, we can use attributes_from_dir. */
1238 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1239 /* Protocol violation: we explicitly clear errno, instead of
1240 setting it to a POSIX error. Callers should use GetLastError. */
1241 errno = 0;
1242 return -1;
1243 } else {
Victor Stinner8c62be82010-05-06 00:08:46 +00001244 /* Could not get attributes on open file. Fall back to
1245 reading the directory. */
1246 if (!attributes_from_dir_w(path, &info)) {
1247 /* Very strange. This should not fail now */
1248 errno = 0;
1249 return -1;
1250 }
1251 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001252 code = attribute_data_to_stat(&info, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00001253 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001254 else {
1255 /* We have a good handle to the target, use it to determine the target
1256 path name (then we'll call lstat on it). */
1257 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_DOS);
1258 if(!buf_size)
1259 return -1;
1260
1261 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
1262 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
1263 buf_size, VOLUME_NAME_DOS);
1264
1265 if(!result_length)
1266 return -1;
1267
1268 if(!CloseHandle(hFile))
1269 return -1;
1270
1271 target_path[result_length] = 0;
1272 code = win32_lstat_w(target_path, result);
1273 free(target_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001274 }
Brian Curtind40e6f72010-07-08 21:39:08 +00001275
Victor Stinner8c62be82010-05-06 00:08:46 +00001276 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001277}
1278
1279static int
1280win32_fstat(int file_number, struct win32_stat *result)
1281{
Victor Stinner8c62be82010-05-06 00:08:46 +00001282 BY_HANDLE_FILE_INFORMATION info;
1283 HANDLE h;
1284 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001285
Victor Stinner8c62be82010-05-06 00:08:46 +00001286 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001287
Victor Stinner8c62be82010-05-06 00:08:46 +00001288 /* Protocol violation: we explicitly clear errno, instead of
1289 setting it to a POSIX error. Callers should use GetLastError. */
1290 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001291
Victor Stinner8c62be82010-05-06 00:08:46 +00001292 if (h == INVALID_HANDLE_VALUE) {
1293 /* This is really a C library error (invalid file handle).
1294 We set the Win32 error to the closes one matching. */
1295 SetLastError(ERROR_INVALID_HANDLE);
1296 return -1;
1297 }
1298 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001299
Victor Stinner8c62be82010-05-06 00:08:46 +00001300 type = GetFileType(h);
1301 if (type == FILE_TYPE_UNKNOWN) {
1302 DWORD error = GetLastError();
1303 if (error != 0) {
1304 return -1;
1305 }
1306 /* else: valid but unknown file */
1307 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001308
Victor Stinner8c62be82010-05-06 00:08:46 +00001309 if (type != FILE_TYPE_DISK) {
1310 if (type == FILE_TYPE_CHAR)
1311 result->st_mode = _S_IFCHR;
1312 else if (type == FILE_TYPE_PIPE)
1313 result->st_mode = _S_IFIFO;
1314 return 0;
1315 }
1316
1317 if (!GetFileInformationByHandle(h, &info)) {
1318 return -1;
1319 }
1320
1321 /* similar to stat() */
1322 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1323 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
Brian Curtin74e45612010-07-09 15:58:59 +00001324 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime,
1325 &result->st_ctime_nsec);
1326 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime,
1327 &result->st_mtime_nsec);
1328 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime,
1329 &result->st_atime_nsec);
Victor Stinner8c62be82010-05-06 00:08:46 +00001330 /* specific to fstat() */
1331 result->st_nlink = info.nNumberOfLinks;
1332 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1333 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001334}
1335
1336#endif /* MS_WINDOWS */
1337
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001338PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001339"stat_result: Result from stat or lstat.\n\n\
1340This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001341 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001342or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1343\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001344Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1345or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001346\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001347See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001348
1349static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001350 {"st_mode", "protection bits"},
1351 {"st_ino", "inode"},
1352 {"st_dev", "device"},
1353 {"st_nlink", "number of hard links"},
1354 {"st_uid", "user ID of owner"},
1355 {"st_gid", "group ID of owner"},
1356 {"st_size", "total size, in bytes"},
1357 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1358 {NULL, "integer time of last access"},
1359 {NULL, "integer time of last modification"},
1360 {NULL, "integer time of last change"},
1361 {"st_atime", "time of last access"},
1362 {"st_mtime", "time of last modification"},
1363 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001364#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001365 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001366#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001367#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001368 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001369#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001370#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001371 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001372#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001373#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001374 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001375#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001376#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001377 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001378#endif
1379#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001380 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001381#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001382 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001383};
1384
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001385#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001386#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001387#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001388#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001389#endif
1390
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001391#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001392#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1393#else
1394#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1395#endif
1396
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001397#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001398#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1399#else
1400#define ST_RDEV_IDX ST_BLOCKS_IDX
1401#endif
1402
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001403#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1404#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1405#else
1406#define ST_FLAGS_IDX ST_RDEV_IDX
1407#endif
1408
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001409#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001410#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001411#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001412#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001413#endif
1414
1415#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1416#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1417#else
1418#define ST_BIRTHTIME_IDX ST_GEN_IDX
1419#endif
1420
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001421static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001422 "stat_result", /* name */
1423 stat_result__doc__, /* doc */
1424 stat_result_fields,
1425 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001426};
1427
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001428PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001429"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1430This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001431 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001432or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001433\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001434See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001435
1436static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001437 {"f_bsize", },
1438 {"f_frsize", },
1439 {"f_blocks", },
1440 {"f_bfree", },
1441 {"f_bavail", },
1442 {"f_files", },
1443 {"f_ffree", },
1444 {"f_favail", },
1445 {"f_flag", },
1446 {"f_namemax",},
1447 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001448};
1449
1450static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001451 "statvfs_result", /* name */
1452 statvfs_result__doc__, /* doc */
1453 statvfs_result_fields,
1454 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001455};
1456
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001457static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001458static PyTypeObject StatResultType;
1459static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001460static newfunc structseq_new;
1461
1462static PyObject *
1463statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1464{
Victor Stinner8c62be82010-05-06 00:08:46 +00001465 PyStructSequence *result;
1466 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001467
Victor Stinner8c62be82010-05-06 00:08:46 +00001468 result = (PyStructSequence*)structseq_new(type, args, kwds);
1469 if (!result)
1470 return NULL;
1471 /* If we have been initialized from a tuple,
1472 st_?time might be set to None. Initialize it
1473 from the int slots. */
1474 for (i = 7; i <= 9; i++) {
1475 if (result->ob_item[i+3] == Py_None) {
1476 Py_DECREF(Py_None);
1477 Py_INCREF(result->ob_item[i]);
1478 result->ob_item[i+3] = result->ob_item[i];
1479 }
1480 }
1481 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001482}
1483
1484
1485
1486/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001487static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001488
1489PyDoc_STRVAR(stat_float_times__doc__,
1490"stat_float_times([newval]) -> oldval\n\n\
1491Determine whether os.[lf]stat represents time stamps as float objects.\n\
1492If newval is True, future calls to stat() return floats, if it is False,\n\
1493future calls return ints. \n\
1494If newval is omitted, return the current setting.\n");
1495
1496static PyObject*
1497stat_float_times(PyObject* self, PyObject *args)
1498{
Victor Stinner8c62be82010-05-06 00:08:46 +00001499 int newval = -1;
1500 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1501 return NULL;
1502 if (newval == -1)
1503 /* Return old value */
1504 return PyBool_FromLong(_stat_float_times);
1505 _stat_float_times = newval;
1506 Py_INCREF(Py_None);
1507 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001508}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001509
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001510static void
1511fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1512{
Victor Stinner8c62be82010-05-06 00:08:46 +00001513 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001514#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinner8c62be82010-05-06 00:08:46 +00001515 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001516#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001517 ival = PyLong_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001518#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001519 if (!ival)
1520 return;
1521 if (_stat_float_times) {
1522 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1523 } else {
1524 fval = ival;
1525 Py_INCREF(fval);
1526 }
1527 PyStructSequence_SET_ITEM(v, index, ival);
1528 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001529}
1530
Tim Peters5aa91602002-01-30 05:46:57 +00001531/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001532 (used by posix_stat() and posix_fstat()) */
1533static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001534_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001535{
Victor Stinner8c62be82010-05-06 00:08:46 +00001536 unsigned long ansec, mnsec, cnsec;
1537 PyObject *v = PyStructSequence_New(&StatResultType);
1538 if (v == NULL)
1539 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001540
Victor Stinner8c62be82010-05-06 00:08:46 +00001541 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001542#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001543 PyStructSequence_SET_ITEM(v, 1,
1544 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001545#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001546 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001547#endif
1548#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001549 PyStructSequence_SET_ITEM(v, 2,
1550 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001551#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001552 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001553#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001554 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1555 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1556 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001557#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001558 PyStructSequence_SET_ITEM(v, 6,
1559 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001560#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001561 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001562#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001563
Martin v. Löwis14694662006-02-03 12:54:16 +00001564#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001565 ansec = st->st_atim.tv_nsec;
1566 mnsec = st->st_mtim.tv_nsec;
1567 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001568#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001569 ansec = st->st_atimespec.tv_nsec;
1570 mnsec = st->st_mtimespec.tv_nsec;
1571 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001572#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001573 ansec = st->st_atime_nsec;
1574 mnsec = st->st_mtime_nsec;
1575 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001576#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001577 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001578#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001579 fill_time(v, 7, st->st_atime, ansec);
1580 fill_time(v, 8, st->st_mtime, mnsec);
1581 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001582
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001583#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001584 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1585 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001586#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001587#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001588 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1589 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001590#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001591#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001592 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1593 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001594#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001595#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001596 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1597 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001598#endif
1599#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001600 {
1601 PyObject *val;
1602 unsigned long bsec,bnsec;
1603 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001604#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner8c62be82010-05-06 00:08:46 +00001605 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001606#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001607 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001608#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001609 if (_stat_float_times) {
1610 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1611 } else {
1612 val = PyLong_FromLong((long)bsec);
1613 }
1614 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1615 val);
1616 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001617#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001618#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001619 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1620 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001621#endif
Fred Drake699f3522000-06-29 21:12:41 +00001622
Victor Stinner8c62be82010-05-06 00:08:46 +00001623 if (PyErr_Occurred()) {
1624 Py_DECREF(v);
1625 return NULL;
1626 }
Fred Drake699f3522000-06-29 21:12:41 +00001627
Victor Stinner8c62be82010-05-06 00:08:46 +00001628 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001629}
1630
Martin v. Löwisd8948722004-06-02 09:57:56 +00001631#ifdef MS_WINDOWS
1632
1633/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1634 where / can be used in place of \ and the trailing slash is optional.
1635 Both SERVER and SHARE must have at least one character.
1636*/
1637
1638#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1639#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001640#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001641#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001642#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001643
Tim Peters4ad82172004-08-30 17:02:04 +00001644static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001645IsUNCRootA(char *path, int pathlen)
1646{
Victor Stinner8c62be82010-05-06 00:08:46 +00001647 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001648
Victor Stinner8c62be82010-05-06 00:08:46 +00001649 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001650
Victor Stinner8c62be82010-05-06 00:08:46 +00001651 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1652 /* minimum UNCRoot is \\x\y */
1653 return FALSE;
1654 for (i = 2; i < pathlen ; i++)
1655 if (ISSLASH(path[i])) break;
1656 if (i == 2 || i == pathlen)
1657 /* do not allow \\\SHARE or \\SERVER */
1658 return FALSE;
1659 share = i+1;
1660 for (i = share; i < pathlen; i++)
1661 if (ISSLASH(path[i])) break;
1662 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001663
Victor Stinner8c62be82010-05-06 00:08:46 +00001664 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001665}
1666
Tim Peters4ad82172004-08-30 17:02:04 +00001667static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001668IsUNCRootW(Py_UNICODE *path, int pathlen)
1669{
Victor Stinner8c62be82010-05-06 00:08:46 +00001670 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001671
Victor Stinner8c62be82010-05-06 00:08:46 +00001672 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001673
Victor Stinner8c62be82010-05-06 00:08:46 +00001674 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1675 /* minimum UNCRoot is \\x\y */
1676 return FALSE;
1677 for (i = 2; i < pathlen ; i++)
1678 if (ISSLASH(path[i])) break;
1679 if (i == 2 || i == pathlen)
1680 /* do not allow \\\SHARE or \\SERVER */
1681 return FALSE;
1682 share = i+1;
1683 for (i = share; i < pathlen; i++)
1684 if (ISSLASH(path[i])) break;
1685 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001686
Victor Stinner8c62be82010-05-06 00:08:46 +00001687 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001688}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001689#endif /* MS_WINDOWS */
1690
Barry Warsaw53699e91996-12-10 23:23:01 +00001691static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001692posix_do_stat(PyObject *self, PyObject *args,
Victor Stinner8c62be82010-05-06 00:08:46 +00001693 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001694#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00001695 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001696#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001697 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001698#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001699 char *wformat,
1700 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001701{
Victor Stinner8c62be82010-05-06 00:08:46 +00001702 STRUCT_STAT st;
1703 PyObject *opath;
1704 char *path;
1705 int res;
1706 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001707
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001708#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001709 PyUnicodeObject *po;
1710 if (PyArg_ParseTuple(args, wformat, &po)) {
1711 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001712
Victor Stinner8c62be82010-05-06 00:08:46 +00001713 Py_BEGIN_ALLOW_THREADS
1714 /* PyUnicode_AS_UNICODE result OK without
1715 thread lock as it is a simple dereference. */
1716 res = wstatfunc(wpath, &st);
1717 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001718
Victor Stinner8c62be82010-05-06 00:08:46 +00001719 if (res != 0)
1720 return win32_error_unicode("stat", wpath);
1721 return _pystat_fromstructstat(&st);
1722 }
1723 /* Drop the argument parsing error as narrow strings
1724 are also valid. */
1725 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001726#endif
1727
Victor Stinner8c62be82010-05-06 00:08:46 +00001728 if (!PyArg_ParseTuple(args, format,
1729 PyUnicode_FSConverter, &opath))
1730 return NULL;
1731 path = PyBytes_AsString(opath);
1732 Py_BEGIN_ALLOW_THREADS
1733 res = (*statfunc)(path, &st);
1734 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001735
Victor Stinner8c62be82010-05-06 00:08:46 +00001736 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001737#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001738 result = win32_error("stat", path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001739#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001740 result = posix_error_with_filename(path);
Martin v. Löwis14694662006-02-03 12:54:16 +00001741#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001742 }
1743 else
1744 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001745
Victor Stinner8c62be82010-05-06 00:08:46 +00001746 Py_DECREF(opath);
1747 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001748}
1749
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001750/* POSIX methods */
1751
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001752PyDoc_STRVAR(posix_access__doc__,
Thomas Wouters9fe394c2007-02-05 01:24:16 +00001753"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001754Use the real uid/gid to test for access to a path. Note that most\n\
1755operations will use the effective uid/gid, therefore this routine can\n\
1756be used in a suid/sgid environment to test if the invoking user has the\n\
1757specified access to the path. The mode argument can be F_OK to test\n\
1758existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001759
1760static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001761posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001762{
Victor Stinner8c62be82010-05-06 00:08:46 +00001763 PyObject *opath;
1764 char *path;
1765 int mode;
1766
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001767#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001768 DWORD attr;
1769 PyUnicodeObject *po;
1770 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1771 Py_BEGIN_ALLOW_THREADS
1772 /* PyUnicode_AS_UNICODE OK without thread lock as
1773 it is a simple dereference. */
1774 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1775 Py_END_ALLOW_THREADS
1776 goto finish;
1777 }
1778 /* Drop the argument parsing error as narrow strings
1779 are also valid. */
1780 PyErr_Clear();
1781 if (!PyArg_ParseTuple(args, "O&i:access",
1782 PyUnicode_FSConverter, &opath, &mode))
1783 return NULL;
1784 path = PyBytes_AsString(opath);
1785 Py_BEGIN_ALLOW_THREADS
1786 attr = GetFileAttributesA(path);
1787 Py_END_ALLOW_THREADS
1788 Py_DECREF(opath);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001789finish:
Victor Stinner8c62be82010-05-06 00:08:46 +00001790 if (attr == 0xFFFFFFFF)
1791 /* File does not exist, or cannot read attributes */
1792 return PyBool_FromLong(0);
1793 /* Access is possible if either write access wasn't requested, or
1794 the file isn't read-only, or if it's a directory, as there are
1795 no read-only directories on Windows. */
1796 return PyBool_FromLong(!(mode & 2)
1797 || !(attr & FILE_ATTRIBUTE_READONLY)
1798 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001799#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001800 int res;
1801 if (!PyArg_ParseTuple(args, "O&i:access",
1802 PyUnicode_FSConverter, &opath, &mode))
1803 return NULL;
1804 path = PyBytes_AsString(opath);
1805 Py_BEGIN_ALLOW_THREADS
1806 res = access(path, mode);
1807 Py_END_ALLOW_THREADS
1808 Py_DECREF(opath);
1809 return PyBool_FromLong(res == 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001810#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001811}
1812
Guido van Rossumd371ff11999-01-25 16:12:23 +00001813#ifndef F_OK
1814#define F_OK 0
1815#endif
1816#ifndef R_OK
1817#define R_OK 4
1818#endif
1819#ifndef W_OK
1820#define W_OK 2
1821#endif
1822#ifndef X_OK
1823#define X_OK 1
1824#endif
1825
1826#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001827PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001828"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001829Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001830
1831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001832posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001833{
Victor Stinner8c62be82010-05-06 00:08:46 +00001834 int id;
1835 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001836
Victor Stinner8c62be82010-05-06 00:08:46 +00001837 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1838 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001839
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001840#if defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001841 /* file descriptor 0 only, the default input device (stdin) */
1842 if (id == 0) {
1843 ret = ttyname();
1844 }
1845 else {
1846 ret = NULL;
1847 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001848#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001849 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001850#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001851 if (ret == NULL)
1852 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001853 return PyUnicode_DecodeFSDefault(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001854}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001855#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001856
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001857#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001858PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001859"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001860Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001861
1862static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001863posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001864{
Victor Stinner8c62be82010-05-06 00:08:46 +00001865 char *ret;
1866 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001867
Greg Wardb48bc172000-03-01 21:51:56 +00001868#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00001869 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001870#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001871 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001872#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001873 if (ret == NULL)
1874 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00001875 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001876}
1877#endif
1878
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001879PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001880"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001881Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001882
Barry Warsaw53699e91996-12-10 23:23:01 +00001883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001884posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001885{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001886#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001887 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001888#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001889 return posix_1str(args, "O&:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001890#elif defined(__VMS)
Victor Stinner8c62be82010-05-06 00:08:46 +00001891 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001892#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001893 return posix_1str(args, "O&:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001894#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001895}
1896
Fred Drake4d1e64b2002-04-15 19:40:07 +00001897#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001898PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001899"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001900Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001901opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001902
1903static PyObject *
1904posix_fchdir(PyObject *self, PyObject *fdobj)
1905{
Victor Stinner8c62be82010-05-06 00:08:46 +00001906 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001907}
1908#endif /* HAVE_FCHDIR */
1909
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001910
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001911PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001912"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001913Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001914
Barry Warsaw53699e91996-12-10 23:23:01 +00001915static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001916posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001917{
Victor Stinner8c62be82010-05-06 00:08:46 +00001918 PyObject *opath = NULL;
1919 char *path = NULL;
1920 int i;
1921 int res;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001922#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001923 DWORD attr;
1924 PyUnicodeObject *po;
1925 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1926 Py_BEGIN_ALLOW_THREADS
1927 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1928 if (attr != 0xFFFFFFFF) {
1929 if (i & _S_IWRITE)
1930 attr &= ~FILE_ATTRIBUTE_READONLY;
1931 else
1932 attr |= FILE_ATTRIBUTE_READONLY;
1933 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1934 }
1935 else
1936 res = 0;
1937 Py_END_ALLOW_THREADS
1938 if (!res)
1939 return win32_error_unicode("chmod",
1940 PyUnicode_AS_UNICODE(po));
1941 Py_INCREF(Py_None);
1942 return Py_None;
1943 }
1944 /* Drop the argument parsing error as narrow strings
1945 are also valid. */
1946 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00001947
Victor Stinner8c62be82010-05-06 00:08:46 +00001948 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1949 &opath, &i))
1950 return NULL;
1951 path = PyBytes_AsString(opath);
1952 Py_BEGIN_ALLOW_THREADS
1953 attr = GetFileAttributesA(path);
1954 if (attr != 0xFFFFFFFF) {
1955 if (i & _S_IWRITE)
1956 attr &= ~FILE_ATTRIBUTE_READONLY;
1957 else
1958 attr |= FILE_ATTRIBUTE_READONLY;
1959 res = SetFileAttributesA(path, attr);
1960 }
1961 else
1962 res = 0;
1963 Py_END_ALLOW_THREADS
1964 if (!res) {
1965 win32_error("chmod", path);
1966 Py_DECREF(opath);
1967 return NULL;
1968 }
1969 Py_DECREF(opath);
1970 Py_INCREF(Py_None);
1971 return Py_None;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001972#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00001973 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1974 &opath, &i))
1975 return NULL;
1976 path = PyBytes_AsString(opath);
1977 Py_BEGIN_ALLOW_THREADS
1978 res = chmod(path, i);
1979 Py_END_ALLOW_THREADS
1980 if (res < 0)
1981 return posix_error_with_allocated_filename(opath);
1982 Py_DECREF(opath);
1983 Py_INCREF(Py_None);
1984 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001985#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001986}
1987
Christian Heimes4e30a842007-11-30 22:12:06 +00001988#ifdef HAVE_FCHMOD
1989PyDoc_STRVAR(posix_fchmod__doc__,
1990"fchmod(fd, mode)\n\n\
1991Change the access permissions of the file given by file\n\
1992descriptor fd.");
1993
1994static PyObject *
1995posix_fchmod(PyObject *self, PyObject *args)
1996{
Victor Stinner8c62be82010-05-06 00:08:46 +00001997 int fd, mode, res;
1998 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1999 return NULL;
2000 Py_BEGIN_ALLOW_THREADS
2001 res = fchmod(fd, mode);
2002 Py_END_ALLOW_THREADS
2003 if (res < 0)
2004 return posix_error();
2005 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002006}
2007#endif /* HAVE_FCHMOD */
2008
2009#ifdef HAVE_LCHMOD
2010PyDoc_STRVAR(posix_lchmod__doc__,
2011"lchmod(path, mode)\n\n\
2012Change the access permissions of a file. If path is a symlink, this\n\
2013affects the link itself rather than the target.");
2014
2015static PyObject *
2016posix_lchmod(PyObject *self, PyObject *args)
2017{
Victor Stinner8c62be82010-05-06 00:08:46 +00002018 PyObject *opath;
2019 char *path;
2020 int i;
2021 int res;
2022 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
2023 &opath, &i))
2024 return NULL;
2025 path = PyBytes_AsString(opath);
2026 Py_BEGIN_ALLOW_THREADS
2027 res = lchmod(path, i);
2028 Py_END_ALLOW_THREADS
2029 if (res < 0)
2030 return posix_error_with_allocated_filename(opath);
2031 Py_DECREF(opath);
2032 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002033}
2034#endif /* HAVE_LCHMOD */
2035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002036
Thomas Wouterscf297e42007-02-23 15:07:44 +00002037#ifdef HAVE_CHFLAGS
2038PyDoc_STRVAR(posix_chflags__doc__,
2039"chflags(path, flags)\n\n\
2040Set file flags.");
2041
2042static PyObject *
2043posix_chflags(PyObject *self, PyObject *args)
2044{
Victor Stinner8c62be82010-05-06 00:08:46 +00002045 PyObject *opath;
2046 char *path;
2047 unsigned long flags;
2048 int res;
2049 if (!PyArg_ParseTuple(args, "O&k:chflags",
2050 PyUnicode_FSConverter, &opath, &flags))
2051 return NULL;
2052 path = PyBytes_AsString(opath);
2053 Py_BEGIN_ALLOW_THREADS
2054 res = chflags(path, flags);
2055 Py_END_ALLOW_THREADS
2056 if (res < 0)
2057 return posix_error_with_allocated_filename(opath);
2058 Py_DECREF(opath);
2059 Py_INCREF(Py_None);
2060 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002061}
2062#endif /* HAVE_CHFLAGS */
2063
2064#ifdef HAVE_LCHFLAGS
2065PyDoc_STRVAR(posix_lchflags__doc__,
2066"lchflags(path, flags)\n\n\
2067Set file flags.\n\
2068This function will not follow symbolic links.");
2069
2070static PyObject *
2071posix_lchflags(PyObject *self, PyObject *args)
2072{
Victor Stinner8c62be82010-05-06 00:08:46 +00002073 PyObject *opath;
2074 char *path;
2075 unsigned long flags;
2076 int res;
2077 if (!PyArg_ParseTuple(args, "O&k:lchflags",
2078 PyUnicode_FSConverter, &opath, &flags))
2079 return NULL;
2080 path = PyBytes_AsString(opath);
2081 Py_BEGIN_ALLOW_THREADS
2082 res = lchflags(path, flags);
2083 Py_END_ALLOW_THREADS
2084 if (res < 0)
2085 return posix_error_with_allocated_filename(opath);
2086 Py_DECREF(opath);
2087 Py_INCREF(Py_None);
2088 return Py_None;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002089}
2090#endif /* HAVE_LCHFLAGS */
2091
Martin v. Löwis244edc82001-10-04 22:44:26 +00002092#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002093PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002094"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002095Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002096
2097static PyObject *
2098posix_chroot(PyObject *self, PyObject *args)
2099{
Victor Stinner8c62be82010-05-06 00:08:46 +00002100 return posix_1str(args, "O&:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002101}
2102#endif
2103
Guido van Rossum21142a01999-01-08 21:05:37 +00002104#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002105PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002106"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002107force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002108
2109static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002110posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002111{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002112 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002113}
2114#endif /* HAVE_FSYNC */
2115
2116#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002117
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002118#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002119extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2120#endif
2121
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002122PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002123"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002124force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002125 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002126
2127static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002128posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002129{
Fred Drake4d1e64b2002-04-15 19:40:07 +00002130 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002131}
2132#endif /* HAVE_FDATASYNC */
2133
2134
Fredrik Lundh10723342000-07-10 16:38:09 +00002135#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002136PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002137"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002138Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002139
Barry Warsaw53699e91996-12-10 23:23:01 +00002140static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002141posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002142{
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:chown",
2148 PyUnicode_FSConverter, &opath,
2149 &uid, &gid))
2150 return NULL;
2151 path = PyBytes_AsString(opath);
2152 Py_BEGIN_ALLOW_THREADS
2153 res = chown(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;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002160}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002161#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002162
Christian Heimes4e30a842007-11-30 22:12:06 +00002163#ifdef HAVE_FCHOWN
2164PyDoc_STRVAR(posix_fchown__doc__,
2165"fchown(fd, uid, gid)\n\n\
2166Change the owner and group id of the file given by file descriptor\n\
2167fd to the numeric uid and gid.");
2168
2169static PyObject *
2170posix_fchown(PyObject *self, PyObject *args)
2171{
Victor Stinner8c62be82010-05-06 00:08:46 +00002172 int fd;
2173 long uid, gid;
2174 int res;
2175 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2176 return NULL;
2177 Py_BEGIN_ALLOW_THREADS
2178 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2179 Py_END_ALLOW_THREADS
2180 if (res < 0)
2181 return posix_error();
2182 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002183}
2184#endif /* HAVE_FCHOWN */
2185
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002186#ifdef HAVE_LCHOWN
2187PyDoc_STRVAR(posix_lchown__doc__,
2188"lchown(path, uid, gid)\n\n\
2189Change the owner and group id of path to the numeric uid and gid.\n\
2190This function will not follow symbolic links.");
2191
2192static PyObject *
2193posix_lchown(PyObject *self, PyObject *args)
2194{
Victor Stinner8c62be82010-05-06 00:08:46 +00002195 PyObject *opath;
2196 char *path;
2197 long uid, gid;
2198 int res;
2199 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2200 PyUnicode_FSConverter, &opath,
2201 &uid, &gid))
2202 return NULL;
2203 path = PyBytes_AsString(opath);
2204 Py_BEGIN_ALLOW_THREADS
2205 res = lchown(path, (uid_t) uid, (gid_t) gid);
2206 Py_END_ALLOW_THREADS
2207 if (res < 0)
2208 return posix_error_with_allocated_filename(opath);
2209 Py_DECREF(opath);
2210 Py_INCREF(Py_None);
2211 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002212}
2213#endif /* HAVE_LCHOWN */
2214
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002215
Guido van Rossum36bc6801995-06-14 22:54:23 +00002216#ifdef HAVE_GETCWD
Barry Warsaw53699e91996-12-10 23:23:01 +00002217static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002218posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002219{
Victor Stinner8c62be82010-05-06 00:08:46 +00002220 char buf[1026];
2221 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002222
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002223#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002224 if (!use_bytes) {
2225 wchar_t wbuf[1026];
2226 wchar_t *wbuf2 = wbuf;
2227 PyObject *resobj;
2228 DWORD len;
2229 Py_BEGIN_ALLOW_THREADS
2230 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2231 /* If the buffer is large enough, len does not include the
2232 terminating \0. If the buffer is too small, len includes
2233 the space needed for the terminator. */
2234 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2235 wbuf2 = malloc(len * sizeof(wchar_t));
2236 if (wbuf2)
2237 len = GetCurrentDirectoryW(len, wbuf2);
2238 }
2239 Py_END_ALLOW_THREADS
2240 if (!wbuf2) {
2241 PyErr_NoMemory();
2242 return NULL;
2243 }
2244 if (!len) {
2245 if (wbuf2 != wbuf) free(wbuf2);
2246 return win32_error("getcwdu", NULL);
2247 }
2248 resobj = PyUnicode_FromWideChar(wbuf2, len);
2249 if (wbuf2 != wbuf) free(wbuf2);
2250 return resobj;
2251 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002252#endif
2253
Victor Stinner8c62be82010-05-06 00:08:46 +00002254 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002255#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002256 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002257#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002258 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002259#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002260 Py_END_ALLOW_THREADS
2261 if (res == NULL)
2262 return posix_error();
2263 if (use_bytes)
2264 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00002265 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002266}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00002267
2268PyDoc_STRVAR(posix_getcwd__doc__,
2269"getcwd() -> path\n\n\
2270Return a unicode string representing the current working directory.");
2271
2272static PyObject *
2273posix_getcwd_unicode(PyObject *self)
2274{
2275 return posix_getcwd(0);
2276}
2277
2278PyDoc_STRVAR(posix_getcwdb__doc__,
2279"getcwdb() -> path\n\n\
2280Return a bytes string representing the current working directory.");
2281
2282static PyObject *
2283posix_getcwd_bytes(PyObject *self)
2284{
2285 return posix_getcwd(1);
2286}
Guido van Rossum36bc6801995-06-14 22:54:23 +00002287#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002288
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002289
Guido van Rossumb6775db1994-08-01 11:34:53 +00002290#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002291PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002292"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002293Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002294
Barry Warsaw53699e91996-12-10 23:23:01 +00002295static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002296posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002297{
Victor Stinner8c62be82010-05-06 00:08:46 +00002298 return posix_2str(args, "O&O&:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002299}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002300#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002301
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002302
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002303PyDoc_STRVAR(posix_listdir__doc__,
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002304"listdir([path]) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002305Return a list containing the names of the entries in the directory.\n\
2306\n\
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002307 path: path of directory to list (default: '.')\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002308\n\
2309The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002310entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002311
Barry Warsaw53699e91996-12-10 23:23:01 +00002312static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002313posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002314{
Victor Stinner8c62be82010-05-06 00:08:46 +00002315 /* XXX Should redo this putting the (now four) versions of opendir
2316 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002317#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002318
Victor Stinner8c62be82010-05-06 00:08:46 +00002319 PyObject *d, *v;
2320 HANDLE hFindFile;
2321 BOOL result;
2322 WIN32_FIND_DATA FileData;
2323 PyObject *opath;
2324 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2325 char *bufptr = namebuf;
2326 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002327
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002328 PyObject *po = NULL;
2329 if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002330 WIN32_FIND_DATAW wFileData;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002331 Py_UNICODE *wnamebuf, *po_wchars;
2332
2333 if (po == NULL) { // Default arg: "."
2334 po_wchars = L".";
2335 len = 1;
2336 } else {
2337 po_wchars = PyUnicode_AS_UNICODE(po);
2338 len = PyUnicode_GET_SIZE(po);
2339 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002340 /* Overallocate for \\*.*\0 */
Victor Stinner8c62be82010-05-06 00:08:46 +00002341 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2342 if (!wnamebuf) {
2343 PyErr_NoMemory();
2344 return NULL;
2345 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002346 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00002347 if (len > 0) {
2348 Py_UNICODE wch = wnamebuf[len-1];
2349 if (wch != L'/' && wch != L'\\' && wch != L':')
2350 wnamebuf[len++] = L'\\';
2351 wcscpy(wnamebuf + len, L"*.*");
2352 }
2353 if ((d = PyList_New(0)) == NULL) {
2354 free(wnamebuf);
2355 return NULL;
2356 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00002357 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002358 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002359 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002360 if (hFindFile == INVALID_HANDLE_VALUE) {
2361 int error = GetLastError();
2362 if (error == ERROR_FILE_NOT_FOUND) {
2363 free(wnamebuf);
2364 return d;
2365 }
2366 Py_DECREF(d);
2367 win32_error_unicode("FindFirstFileW", wnamebuf);
2368 free(wnamebuf);
2369 return NULL;
2370 }
2371 do {
2372 /* Skip over . and .. */
2373 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2374 wcscmp(wFileData.cFileName, L"..") != 0) {
2375 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2376 if (v == NULL) {
2377 Py_DECREF(d);
2378 d = NULL;
2379 break;
2380 }
2381 if (PyList_Append(d, v) != 0) {
2382 Py_DECREF(v);
2383 Py_DECREF(d);
2384 d = NULL;
2385 break;
2386 }
2387 Py_DECREF(v);
2388 }
2389 Py_BEGIN_ALLOW_THREADS
2390 result = FindNextFileW(hFindFile, &wFileData);
2391 Py_END_ALLOW_THREADS
2392 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2393 it got to the end of the directory. */
2394 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2395 Py_DECREF(d);
2396 win32_error_unicode("FindNextFileW", wnamebuf);
2397 FindClose(hFindFile);
2398 free(wnamebuf);
2399 return NULL;
2400 }
2401 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002402
Victor Stinner8c62be82010-05-06 00:08:46 +00002403 if (FindClose(hFindFile) == FALSE) {
2404 Py_DECREF(d);
2405 win32_error_unicode("FindClose", wnamebuf);
2406 free(wnamebuf);
2407 return NULL;
2408 }
2409 free(wnamebuf);
2410 return d;
2411 }
2412 /* Drop the argument parsing error as narrow strings
2413 are also valid. */
2414 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002415
Victor Stinner8c62be82010-05-06 00:08:46 +00002416 if (!PyArg_ParseTuple(args, "O&:listdir",
2417 PyUnicode_FSConverter, &opath))
2418 return NULL;
2419 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) {
2420 PyErr_SetString(PyExc_ValueError, "path too long");
2421 Py_DECREF(opath);
2422 return NULL;
2423 }
2424 strcpy(namebuf, PyBytes_AsString(opath));
2425 len = PyObject_Size(opath);
2426 if (len > 0) {
2427 char ch = namebuf[len-1];
2428 if (ch != SEP && ch != ALTSEP && ch != ':')
2429 namebuf[len++] = '/';
2430 strcpy(namebuf + len, "*.*");
2431 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002432
Victor Stinner8c62be82010-05-06 00:08:46 +00002433 if ((d = PyList_New(0)) == NULL)
2434 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002435
Antoine Pitroub73caab2010-08-09 23:39:31 +00002436 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002437 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00002438 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002439 if (hFindFile == INVALID_HANDLE_VALUE) {
2440 int error = GetLastError();
2441 if (error == ERROR_FILE_NOT_FOUND)
2442 return d;
2443 Py_DECREF(d);
2444 return win32_error("FindFirstFile", namebuf);
2445 }
2446 do {
2447 /* Skip over . and .. */
2448 if (strcmp(FileData.cFileName, ".") != 0 &&
2449 strcmp(FileData.cFileName, "..") != 0) {
2450 v = PyBytes_FromString(FileData.cFileName);
2451 if (v == NULL) {
2452 Py_DECREF(d);
2453 d = NULL;
2454 break;
2455 }
2456 if (PyList_Append(d, v) != 0) {
2457 Py_DECREF(v);
2458 Py_DECREF(d);
2459 d = NULL;
2460 break;
2461 }
2462 Py_DECREF(v);
2463 }
2464 Py_BEGIN_ALLOW_THREADS
2465 result = FindNextFile(hFindFile, &FileData);
2466 Py_END_ALLOW_THREADS
2467 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2468 it got to the end of the directory. */
2469 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2470 Py_DECREF(d);
2471 win32_error("FindNextFile", namebuf);
2472 FindClose(hFindFile);
2473 return NULL;
2474 }
2475 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002476
Victor Stinner8c62be82010-05-06 00:08:46 +00002477 if (FindClose(hFindFile) == FALSE) {
2478 Py_DECREF(d);
2479 return win32_error("FindClose", namebuf);
2480 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002481
Victor Stinner8c62be82010-05-06 00:08:46 +00002482 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002483
Tim Peters0bb44a42000-09-15 07:44:49 +00002484#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002485
2486#ifndef MAX_PATH
2487#define MAX_PATH CCHMAXPATH
2488#endif
Martin v. Löwis011e8422009-05-05 04:43:17 +00002489 PyObject *oname;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002490 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002491 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002492 PyObject *d, *v;
2493 char namebuf[MAX_PATH+5];
2494 HDIR hdir = 1;
2495 ULONG srchcnt = 1;
2496 FILEFINDBUF3 ep;
2497 APIRET rc;
2498
Victor Stinner8c62be82010-05-06 00:08:46 +00002499 if (!PyArg_ParseTuple(args, "O&:listdir",
Martin v. Löwis011e8422009-05-05 04:43:17 +00002500 PyUnicode_FSConverter, &oname))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002501 return NULL;
Victor Stinnerdcb24032010-04-22 12:08:36 +00002502 name = PyBytes_AsString(oname);
2503 len = PyBytes_GET_SIZE(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002504 if (len >= MAX_PATH) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002505 Py_DECREF(oname);
Neal Norwitz6c913782007-10-14 03:23:09 +00002506 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002507 return NULL;
2508 }
2509 strcpy(namebuf, name);
2510 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002511 if (*pt == ALTSEP)
2512 *pt = SEP;
2513 if (namebuf[len-1] != SEP)
2514 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002515 strcpy(namebuf + len, "*.*");
2516
Neal Norwitz6c913782007-10-14 03:23:09 +00002517 if ((d = PyList_New(0)) == NULL) {
Victor Stinnerdcb24032010-04-22 12:08:36 +00002518 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002519 return NULL;
Alexandre Vassalotti4167ebc2007-10-14 02:54:41 +00002520 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002521
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002522 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2523 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002524 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002525 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2526 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2527 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002528
2529 if (rc != NO_ERROR) {
2530 errno = ENOENT;
Martin v. Löwis011e8422009-05-05 04:43:17 +00002531 return posix_error_with_allocated_filename(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002532 }
2533
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002534 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002535 do {
2536 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002537 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002538 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002539
2540 strcpy(namebuf, ep.achName);
2541
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002542 /* Leave Case of Name Alone -- In Native Form */
2543 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002544
Christian Heimes72b710a2008-05-26 13:28:38 +00002545 v = PyBytes_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002546 if (v == NULL) {
2547 Py_DECREF(d);
2548 d = NULL;
2549 break;
2550 }
2551 if (PyList_Append(d, v) != 0) {
2552 Py_DECREF(v);
2553 Py_DECREF(d);
2554 d = NULL;
2555 break;
2556 }
2557 Py_DECREF(v);
2558 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2559 }
2560
Victor Stinnerdcb24032010-04-22 12:08:36 +00002561 Py_DECREF(oname);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002562 return d;
2563#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002564 PyObject *oname;
2565 char *name;
2566 PyObject *d, *v;
2567 DIR *dirp;
2568 struct dirent *ep;
2569 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002570
Victor Stinner8c62be82010-05-06 00:08:46 +00002571 errno = 0;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002572 /* v is never read, so it does not need to be initialized yet. */
2573 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002574 arg_is_unicode = 0;
2575 PyErr_Clear();
2576 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002577 oname = NULL;
2578 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
Victor Stinner8c62be82010-05-06 00:08:46 +00002579 return NULL;
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00002580 if (oname == NULL) { // Default arg: "."
2581 oname = PyBytes_FromString(".");
2582 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002583 name = PyBytes_AsString(oname);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002584 Py_BEGIN_ALLOW_THREADS
2585 dirp = opendir(name);
2586 Py_END_ALLOW_THREADS
2587 if (dirp == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00002588 return posix_error_with_allocated_filename(oname);
2589 }
2590 if ((d = PyList_New(0)) == NULL) {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002591 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002592 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002593 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002594 Py_DECREF(oname);
2595 return NULL;
2596 }
2597 for (;;) {
2598 errno = 0;
2599 Py_BEGIN_ALLOW_THREADS
2600 ep = readdir(dirp);
2601 Py_END_ALLOW_THREADS
2602 if (ep == NULL) {
2603 if (errno == 0) {
2604 break;
2605 } else {
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002606 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002607 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002608 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002609 Py_DECREF(d);
2610 return posix_error_with_allocated_filename(oname);
2611 }
2612 }
2613 if (ep->d_name[0] == '.' &&
2614 (NAMLEN(ep) == 1 ||
2615 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2616 continue;
Victor Stinnera45598a2010-05-14 16:35:39 +00002617 if (arg_is_unicode)
2618 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
2619 else
2620 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00002621 if (v == NULL) {
Victor Stinnera45598a2010-05-14 16:35:39 +00002622 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002623 break;
2624 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002625 if (PyList_Append(d, v) != 0) {
2626 Py_DECREF(v);
Victor Stinnera45598a2010-05-14 16:35:39 +00002627 Py_CLEAR(d);
Victor Stinner8c62be82010-05-06 00:08:46 +00002628 break;
2629 }
2630 Py_DECREF(v);
2631 }
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002632 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002633 closedir(dirp);
Antoine Pitroud3ccde82010-09-04 17:21:57 +00002634 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00002635 Py_DECREF(oname);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002636
Victor Stinner8c62be82010-05-06 00:08:46 +00002637 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002638
Tim Peters0bb44a42000-09-15 07:44:49 +00002639#endif /* which OS */
2640} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002641
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002642#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002643/* A helper function for abspath on win32 */
2644static PyObject *
2645posix__getfullpathname(PyObject *self, PyObject *args)
2646{
Victor Stinner8c62be82010-05-06 00:08:46 +00002647 PyObject *opath;
2648 char *path;
2649 char outbuf[MAX_PATH*2];
2650 char *temp;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002651#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002652 PyUnicodeObject *po;
2653 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2654 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2655 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2656 Py_UNICODE *wtemp;
2657 DWORD result;
2658 PyObject *v;
2659 result = GetFullPathNameW(wpath,
2660 sizeof(woutbuf)/sizeof(woutbuf[0]),
2661 woutbuf, &wtemp);
2662 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2663 woutbufp = malloc(result * sizeof(Py_UNICODE));
2664 if (!woutbufp)
2665 return PyErr_NoMemory();
2666 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2667 }
2668 if (result)
2669 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2670 else
2671 v = win32_error_unicode("GetFullPathNameW", wpath);
2672 if (woutbufp != woutbuf)
2673 free(woutbufp);
2674 return v;
2675 }
2676 /* Drop the argument parsing error as narrow strings
2677 are also valid. */
2678 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002679
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002680#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002681 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2682 PyUnicode_FSConverter, &opath))
2683 return NULL;
2684 path = PyBytes_AsString(opath);
2685 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2686 outbuf, &temp)) {
2687 win32_error("GetFullPathName", path);
2688 Py_DECREF(opath);
2689 return NULL;
2690 }
2691 Py_DECREF(opath);
2692 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2693 return PyUnicode_Decode(outbuf, strlen(outbuf),
2694 Py_FileSystemDefaultEncoding, NULL);
2695 }
2696 return PyBytes_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002697} /* end of posix__getfullpathname */
Brian Curtind40e6f72010-07-08 21:39:08 +00002698
2699/* A helper function for samepath on windows */
2700static PyObject *
2701posix__getfinalpathname(PyObject *self, PyObject *args)
2702{
2703 HANDLE hFile;
2704 int buf_size;
2705 wchar_t *target_path;
2706 int result_length;
2707 PyObject *result;
2708 wchar_t *path;
2709
2710 if (!PyArg_ParseTuple(args, "u|:_getfullpathname", &path)) {
2711 return NULL;
2712 }
2713
2714 if(!check_GetFinalPathNameByHandle()) {
2715 /* If the OS doesn't have GetFinalPathNameByHandle, return a
2716 NotImplementedError. */
2717 return PyErr_Format(PyExc_NotImplementedError,
2718 "GetFinalPathNameByHandle not available on this platform");
2719 }
2720
2721 hFile = CreateFileW(
2722 path,
2723 0, /* desired access */
2724 0, /* share mode */
2725 NULL, /* security attributes */
2726 OPEN_EXISTING,
2727 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
2728 FILE_FLAG_BACKUP_SEMANTICS,
2729 NULL);
2730
2731 if(hFile == INVALID_HANDLE_VALUE) {
2732 return win32_error_unicode("GetFinalPathNamyByHandle", path);
Brian Curtin74e45612010-07-09 15:58:59 +00002733 return PyErr_Format(PyExc_RuntimeError,
2734 "Could not get a handle to file.");
Brian Curtind40e6f72010-07-08 21:39:08 +00002735 }
2736
2737 /* We have a good handle to the target, use it to determine the
2738 target path name. */
2739 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
2740
2741 if(!buf_size)
2742 return win32_error_unicode("GetFinalPathNameByHandle", path);
2743
2744 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
2745 if(!target_path)
2746 return PyErr_NoMemory();
2747
2748 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
2749 buf_size, VOLUME_NAME_DOS);
2750 if(!result_length)
2751 return win32_error_unicode("GetFinalPathNamyByHandle", path);
2752
2753 if(!CloseHandle(hFile))
2754 return win32_error_unicode("GetFinalPathNameByHandle", path);
2755
2756 target_path[result_length] = 0;
2757 result = PyUnicode_FromUnicode(target_path, result_length);
2758 free(target_path);
2759 return result;
2760
2761} /* end of posix__getfinalpathname */
Brian Curtin62857742010-09-06 17:07:27 +00002762
2763static PyObject *
2764posix__getfileinformation(PyObject *self, PyObject *args)
2765{
2766 HANDLE hFile;
2767 BY_HANDLE_FILE_INFORMATION info;
2768 int fd;
2769
2770 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
2771 return NULL;
2772
2773 if (!_PyVerify_fd(fd)) {
2774 PyErr_SetString(PyExc_ValueError, "received invalid file descriptor");
2775 return NULL;
2776 }
2777
2778 hFile = (HANDLE)_get_osfhandle(fd);
2779 if (hFile == INVALID_HANDLE_VALUE)
2780 return win32_error("_getfileinformation", NULL);
2781
2782 if (!GetFileInformationByHandle(hFile, &info))
2783 return win32_error("_getfileinformation", NULL);
2784
2785 return Py_BuildValue("iii", info.dwVolumeSerialNumber,
2786 info.nFileIndexHigh,
2787 info.nFileIndexLow);
2788}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002789#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002790
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002791PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002792"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002793Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002794
Barry Warsaw53699e91996-12-10 23:23:01 +00002795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002796posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002797{
Victor Stinner8c62be82010-05-06 00:08:46 +00002798 int res;
2799 PyObject *opath;
2800 char *path;
2801 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002802
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002803#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002804 PyUnicodeObject *po;
2805 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2806 Py_BEGIN_ALLOW_THREADS
2807 /* PyUnicode_AS_UNICODE OK without thread lock as
2808 it is a simple dereference. */
2809 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2810 Py_END_ALLOW_THREADS
2811 if (!res)
2812 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2813 Py_INCREF(Py_None);
2814 return Py_None;
2815 }
2816 /* Drop the argument parsing error as narrow strings
2817 are also valid. */
2818 PyErr_Clear();
2819 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2820 PyUnicode_FSConverter, &opath, &mode))
2821 return NULL;
2822 path = PyBytes_AsString(opath);
2823 Py_BEGIN_ALLOW_THREADS
2824 /* PyUnicode_AS_UNICODE OK without thread lock as
2825 it is a simple dereference. */
2826 res = CreateDirectoryA(path, NULL);
2827 Py_END_ALLOW_THREADS
2828 if (!res) {
2829 win32_error("mkdir", path);
2830 Py_DECREF(opath);
2831 return NULL;
2832 }
2833 Py_DECREF(opath);
2834 Py_INCREF(Py_None);
2835 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002836#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002837
Victor Stinner8c62be82010-05-06 00:08:46 +00002838 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2839 PyUnicode_FSConverter, &opath, &mode))
2840 return NULL;
2841 path = PyBytes_AsString(opath);
2842 Py_BEGIN_ALLOW_THREADS
Thomas Wouters477c8d52006-05-27 19:21:47 +00002843#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinner8c62be82010-05-06 00:08:46 +00002844 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002845#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002846 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002847#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002848 Py_END_ALLOW_THREADS
2849 if (res < 0)
2850 return posix_error_with_allocated_filename(opath);
2851 Py_DECREF(opath);
2852 Py_INCREF(Py_None);
2853 return Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002854#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002855}
2856
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002857
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002858/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2859#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002860#include <sys/resource.h>
2861#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002862
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002863
2864#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002865PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002866"nice(inc) -> new_priority\n\n\
2867Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002868
Barry Warsaw53699e91996-12-10 23:23:01 +00002869static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002870posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002871{
Victor Stinner8c62be82010-05-06 00:08:46 +00002872 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002873
Victor Stinner8c62be82010-05-06 00:08:46 +00002874 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2875 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002876
Victor Stinner8c62be82010-05-06 00:08:46 +00002877 /* There are two flavours of 'nice': one that returns the new
2878 priority (as required by almost all standards out there) and the
2879 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2880 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002881
Victor Stinner8c62be82010-05-06 00:08:46 +00002882 If we are of the nice family that returns the new priority, we
2883 need to clear errno before the call, and check if errno is filled
2884 before calling posix_error() on a returnvalue of -1, because the
2885 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002886
Victor Stinner8c62be82010-05-06 00:08:46 +00002887 errno = 0;
2888 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002889#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00002890 if (value == 0)
2891 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002892#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002893 if (value == -1 && errno != 0)
2894 /* either nice() or getpriority() returned an error */
2895 return posix_error();
2896 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002897}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002898#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002899
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002900PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002901"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002902Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002903
Barry Warsaw53699e91996-12-10 23:23:01 +00002904static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002905posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002906{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002907#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002908 PyObject *o1, *o2;
2909 char *p1, *p2;
2910 BOOL result;
2911 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2912 goto error;
2913 if (!convert_to_unicode(&o1))
2914 goto error;
2915 if (!convert_to_unicode(&o2)) {
2916 Py_DECREF(o1);
2917 goto error;
2918 }
2919 Py_BEGIN_ALLOW_THREADS
2920 result = MoveFileW(PyUnicode_AsUnicode(o1),
2921 PyUnicode_AsUnicode(o2));
2922 Py_END_ALLOW_THREADS
2923 Py_DECREF(o1);
2924 Py_DECREF(o2);
2925 if (!result)
2926 return win32_error("rename", NULL);
2927 Py_INCREF(Py_None);
2928 return Py_None;
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002929error:
Victor Stinner8c62be82010-05-06 00:08:46 +00002930 PyErr_Clear();
2931 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2932 return NULL;
2933 Py_BEGIN_ALLOW_THREADS
2934 result = MoveFileA(p1, p2);
2935 Py_END_ALLOW_THREADS
2936 if (!result)
2937 return win32_error("rename", NULL);
2938 Py_INCREF(Py_None);
2939 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002940#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002941 return posix_2str(args, "O&O&:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002942#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002943}
2944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002945
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002946PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002947"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002948Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002949
Barry Warsaw53699e91996-12-10 23:23:01 +00002950static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002951posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002952{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002953#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002954 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002955#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002956 return posix_1str(args, "O&:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002957#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002958}
2959
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002960
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002961PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002962"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002963Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002964
Barry Warsaw53699e91996-12-10 23:23:01 +00002965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002966posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002967{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002968#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00002969 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002970#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002971 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002972#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002973}
2974
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002975
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002976#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002977PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002978"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002979Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002980
Barry Warsaw53699e91996-12-10 23:23:01 +00002981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002982posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002983{
Victor Stinner8c62be82010-05-06 00:08:46 +00002984 long sts;
Amaury Forgeot d'Arc90ebd3e2007-11-20 01:52:14 +00002985#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002986 wchar_t *command;
2987 if (!PyArg_ParseTuple(args, "u:system", &command))
2988 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002989
Victor Stinner8c62be82010-05-06 00:08:46 +00002990 Py_BEGIN_ALLOW_THREADS
2991 sts = _wsystem(command);
2992 Py_END_ALLOW_THREADS
Victor Stinnercfa72782010-04-16 11:45:13 +00002993#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002994 PyObject *command_obj;
2995 char *command;
2996 if (!PyArg_ParseTuple(args, "O&:system",
2997 PyUnicode_FSConverter, &command_obj))
2998 return NULL;
Victor Stinnercfa72782010-04-16 11:45:13 +00002999
Victor Stinner8c62be82010-05-06 00:08:46 +00003000 command = PyBytes_AsString(command_obj);
3001 Py_BEGIN_ALLOW_THREADS
3002 sts = system(command);
3003 Py_END_ALLOW_THREADS
3004 Py_DECREF(command_obj);
Victor Stinnercfa72782010-04-16 11:45:13 +00003005#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003006 return PyLong_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003007}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003008#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003009
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003010
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003011PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003012"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003013Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003014
Barry Warsaw53699e91996-12-10 23:23:01 +00003015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003016posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003017{
Victor Stinner8c62be82010-05-06 00:08:46 +00003018 int i;
3019 if (!PyArg_ParseTuple(args, "i:umask", &i))
3020 return NULL;
3021 i = (int)umask(i);
3022 if (i < 0)
3023 return posix_error();
3024 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003025}
3026
Brian Curtind40e6f72010-07-08 21:39:08 +00003027#ifdef MS_WINDOWS
3028
3029/* override the default DeleteFileW behavior so that directory
3030symlinks can be removed with this function, the same as with
3031Unix symlinks */
3032BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
3033{
3034 WIN32_FILE_ATTRIBUTE_DATA info;
3035 WIN32_FIND_DATAW find_data;
3036 HANDLE find_data_handle;
3037 int is_directory = 0;
3038 int is_link = 0;
3039
3040 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
3041 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
3042
3043 /* Get WIN32_FIND_DATA structure for the path to determine if
3044 it is a symlink */
3045 if(is_directory &&
3046 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
3047 find_data_handle = FindFirstFileW(lpFileName, &find_data);
3048
3049 if(find_data_handle != INVALID_HANDLE_VALUE) {
3050 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
3051 FindClose(find_data_handle);
3052 }
3053 }
3054 }
3055
3056 if (is_directory && is_link)
3057 return RemoveDirectoryW(lpFileName);
3058
3059 return DeleteFileW(lpFileName);
3060}
3061#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003062
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003063PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003064"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003065Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003066
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003067PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003068"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003069Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003070
Barry Warsaw53699e91996-12-10 23:23:01 +00003071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003072posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003073{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003074#ifdef MS_WINDOWS
Brian Curtin74e45612010-07-09 15:58:59 +00003075 return win32_1str(args, "remove", "y:remove", DeleteFileA,
3076 "U:remove", Py_DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003077#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003078 return posix_1str(args, "O&:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003079#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003080}
3081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003082
Guido van Rossumb6775db1994-08-01 11:34:53 +00003083#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003084PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003085"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003086Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003087
Barry Warsaw53699e91996-12-10 23:23:01 +00003088static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003089posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003090{
Victor Stinner8c62be82010-05-06 00:08:46 +00003091 struct utsname u;
3092 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00003093
Victor Stinner8c62be82010-05-06 00:08:46 +00003094 Py_BEGIN_ALLOW_THREADS
3095 res = uname(&u);
3096 Py_END_ALLOW_THREADS
3097 if (res < 0)
3098 return posix_error();
3099 return Py_BuildValue("(sssss)",
3100 u.sysname,
3101 u.nodename,
3102 u.release,
3103 u.version,
3104 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00003105}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003106#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003107
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003108static int
3109extract_time(PyObject *t, long* sec, long* usec)
3110{
Victor Stinner8c62be82010-05-06 00:08:46 +00003111 long intval;
3112 if (PyFloat_Check(t)) {
3113 double tval = PyFloat_AsDouble(t);
3114 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
3115 if (!intobj)
3116 return -1;
3117 intval = PyLong_AsLong(intobj);
3118 Py_DECREF(intobj);
3119 if (intval == -1 && PyErr_Occurred())
3120 return -1;
3121 *sec = intval;
3122 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
3123 if (*usec < 0)
3124 /* If rounding gave us a negative number,
3125 truncate. */
3126 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00003127 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00003128 }
3129 intval = PyLong_AsLong(t);
3130 if (intval == -1 && PyErr_Occurred())
3131 return -1;
3132 *sec = intval;
3133 *usec = 0;
3134 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003135}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003136
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003137PyDoc_STRVAR(posix_utime__doc__,
Thomas Wouters477c8d52006-05-27 19:21:47 +00003138"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00003139utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00003140Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003141second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003142
Barry Warsaw53699e91996-12-10 23:23:01 +00003143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003144posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003145{
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003146#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003147 PyObject *arg;
3148 PyUnicodeObject *obwpath;
3149 wchar_t *wpath = NULL;
3150 PyObject *oapath;
3151 char *apath;
3152 HANDLE hFile;
3153 long atimesec, mtimesec, ausec, musec;
3154 FILETIME atime, mtime;
3155 PyObject *result = NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003156
Victor Stinner8c62be82010-05-06 00:08:46 +00003157 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
3158 wpath = PyUnicode_AS_UNICODE(obwpath);
3159 Py_BEGIN_ALLOW_THREADS
3160 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
3161 NULL, OPEN_EXISTING,
3162 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3163 Py_END_ALLOW_THREADS
3164 if (hFile == INVALID_HANDLE_VALUE)
3165 return win32_error_unicode("utime", wpath);
3166 } else
3167 /* Drop the argument parsing error as narrow strings
3168 are also valid. */
3169 PyErr_Clear();
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003170
Victor Stinner8c62be82010-05-06 00:08:46 +00003171 if (!wpath) {
3172 if (!PyArg_ParseTuple(args, "O&O:utime",
3173 PyUnicode_FSConverter, &oapath, &arg))
3174 return NULL;
3175 apath = PyBytes_AsString(oapath);
3176 Py_BEGIN_ALLOW_THREADS
3177 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3178 NULL, OPEN_EXISTING,
3179 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3180 Py_END_ALLOW_THREADS
3181 if (hFile == INVALID_HANDLE_VALUE) {
3182 win32_error("utime", apath);
3183 Py_DECREF(oapath);
3184 return NULL;
3185 }
3186 Py_DECREF(oapath);
3187 }
3188
3189 if (arg == Py_None) {
3190 SYSTEMTIME now;
3191 GetSystemTime(&now);
3192 if (!SystemTimeToFileTime(&now, &mtime) ||
3193 !SystemTimeToFileTime(&now, &atime)) {
3194 win32_error("utime", NULL);
3195 goto done;
3196 }
3197 }
3198 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3199 PyErr_SetString(PyExc_TypeError,
3200 "utime() arg 2 must be a tuple (atime, mtime)");
3201 goto done;
3202 }
3203 else {
3204 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3205 &atimesec, &ausec) == -1)
3206 goto done;
3207 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3208 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3209 &mtimesec, &musec) == -1)
3210 goto done;
3211 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3212 }
3213 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3214 /* Avoid putting the file name into the error here,
3215 as that may confuse the user into believing that
3216 something is wrong with the file, when it also
3217 could be the time stamp that gives a problem. */
3218 win32_error("utime", NULL);
3219 }
3220 Py_INCREF(Py_None);
3221 result = Py_None;
Thomas Wouters477c8d52006-05-27 19:21:47 +00003222done:
Victor Stinner8c62be82010-05-06 00:08:46 +00003223 CloseHandle(hFile);
3224 return result;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003225#else /* MS_WINDOWS */
Thomas Wouters477c8d52006-05-27 19:21:47 +00003226
Victor Stinner8c62be82010-05-06 00:08:46 +00003227 PyObject *opath;
3228 char *path;
3229 long atime, mtime, ausec, musec;
3230 int res;
3231 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003232
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003233#if defined(HAVE_UTIMES)
Victor Stinner8c62be82010-05-06 00:08:46 +00003234 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003235#define ATIME buf[0].tv_sec
3236#define MTIME buf[1].tv_sec
3237#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003238/* XXX should define struct utimbuf instead, above */
Victor Stinner8c62be82010-05-06 00:08:46 +00003239 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003240#define ATIME buf.actime
3241#define MTIME buf.modtime
3242#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003243#else /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003244 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003245#define ATIME buf[0]
3246#define MTIME buf[1]
3247#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003248#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003249
Mark Hammond817c9292003-12-03 01:22:38 +00003250
Victor Stinner8c62be82010-05-06 00:08:46 +00003251 if (!PyArg_ParseTuple(args, "O&O:utime",
3252 PyUnicode_FSConverter, &opath, &arg))
3253 return NULL;
3254 path = PyBytes_AsString(opath);
3255 if (arg == Py_None) {
3256 /* optional time values not given */
3257 Py_BEGIN_ALLOW_THREADS
3258 res = utime(path, NULL);
3259 Py_END_ALLOW_THREADS
3260 }
3261 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3262 PyErr_SetString(PyExc_TypeError,
3263 "utime() arg 2 must be a tuple (atime, mtime)");
3264 Py_DECREF(opath);
3265 return NULL;
3266 }
3267 else {
3268 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3269 &atime, &ausec) == -1) {
3270 Py_DECREF(opath);
3271 return NULL;
3272 }
3273 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3274 &mtime, &musec) == -1) {
3275 Py_DECREF(opath);
3276 return NULL;
3277 }
3278 ATIME = atime;
3279 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003280#ifdef HAVE_UTIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00003281 buf[0].tv_usec = ausec;
3282 buf[1].tv_usec = musec;
3283 Py_BEGIN_ALLOW_THREADS
3284 res = utimes(path, buf);
3285 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003286#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 Py_BEGIN_ALLOW_THREADS
3288 res = utime(path, UTIME_ARG);
3289 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003290#endif /* HAVE_UTIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00003291 }
3292 if (res < 0) {
3293 return posix_error_with_allocated_filename(opath);
3294 }
3295 Py_DECREF(opath);
3296 Py_INCREF(Py_None);
3297 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003298#undef UTIME_ARG
3299#undef ATIME
3300#undef MTIME
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003301#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003302}
3303
Guido van Rossum85e3b011991-06-03 12:42:10 +00003304
Guido van Rossum3b066191991-06-04 19:40:25 +00003305/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003306
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003307PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003308"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003309Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003310
Barry Warsaw53699e91996-12-10 23:23:01 +00003311static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003312posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003313{
Victor Stinner8c62be82010-05-06 00:08:46 +00003314 int sts;
3315 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3316 return NULL;
3317 _exit(sts);
3318 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003319}
3320
Martin v. Löwis114619e2002-10-07 06:44:21 +00003321#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3322static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003323free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003324{
Victor Stinner8c62be82010-05-06 00:08:46 +00003325 Py_ssize_t i;
3326 for (i = 0; i < count; i++)
3327 PyMem_Free(array[i]);
3328 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003329}
Martin v. Löwis011e8422009-05-05 04:43:17 +00003330
Antoine Pitrou69f71142009-05-24 21:25:49 +00003331static
Martin v. Löwis011e8422009-05-05 04:43:17 +00003332int fsconvert_strdup(PyObject *o, char**out)
3333{
Victor Stinner8c62be82010-05-06 00:08:46 +00003334 PyObject *bytes;
3335 Py_ssize_t size;
3336 if (!PyUnicode_FSConverter(o, &bytes))
3337 return 0;
3338 size = PyBytes_GET_SIZE(bytes);
3339 *out = PyMem_Malloc(size+1);
3340 if (!*out)
3341 return 0;
3342 memcpy(*out, PyBytes_AsString(bytes), size+1);
3343 Py_DECREF(bytes);
3344 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00003345}
Martin v. Löwis114619e2002-10-07 06:44:21 +00003346#endif
3347
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003348
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003349#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003350PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003351"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003352Execute an executable path with arguments, replacing current process.\n\
3353\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003354 path: path of executable file\n\
3355 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003356
Barry Warsaw53699e91996-12-10 23:23:01 +00003357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003358posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003359{
Victor Stinner8c62be82010-05-06 00:08:46 +00003360 PyObject *opath;
3361 char *path;
3362 PyObject *argv;
3363 char **argvlist;
3364 Py_ssize_t i, argc;
3365 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003366
Victor Stinner8c62be82010-05-06 00:08:46 +00003367 /* execv has two arguments: (path, argv), where
3368 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003369
Victor Stinner8c62be82010-05-06 00:08:46 +00003370 if (!PyArg_ParseTuple(args, "O&O:execv",
3371 PyUnicode_FSConverter,
3372 &opath, &argv))
3373 return NULL;
3374 path = PyBytes_AsString(opath);
3375 if (PyList_Check(argv)) {
3376 argc = PyList_Size(argv);
3377 getitem = PyList_GetItem;
3378 }
3379 else if (PyTuple_Check(argv)) {
3380 argc = PyTuple_Size(argv);
3381 getitem = PyTuple_GetItem;
3382 }
3383 else {
3384 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3385 Py_DECREF(opath);
3386 return NULL;
3387 }
3388 if (argc < 1) {
3389 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3390 Py_DECREF(opath);
3391 return NULL;
3392 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003393
Victor Stinner8c62be82010-05-06 00:08:46 +00003394 argvlist = PyMem_NEW(char *, argc+1);
3395 if (argvlist == NULL) {
3396 Py_DECREF(opath);
3397 return PyErr_NoMemory();
3398 }
3399 for (i = 0; i < argc; i++) {
3400 if (!fsconvert_strdup((*getitem)(argv, i),
3401 &argvlist[i])) {
3402 free_string_array(argvlist, i);
3403 PyErr_SetString(PyExc_TypeError,
3404 "execv() arg 2 must contain only strings");
3405 Py_DECREF(opath);
3406 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003407
Victor Stinner8c62be82010-05-06 00:08:46 +00003408 }
3409 }
3410 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003411
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003413
Victor Stinner8c62be82010-05-06 00:08:46 +00003414 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003415
Victor Stinner8c62be82010-05-06 00:08:46 +00003416 free_string_array(argvlist, argc);
3417 Py_DECREF(opath);
3418 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003419}
3420
Victor Stinner13bb71c2010-04-23 21:41:56 +00003421static char**
3422parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3423{
Victor Stinner8c62be82010-05-06 00:08:46 +00003424 char **envlist;
3425 Py_ssize_t i, pos, envc;
3426 PyObject *keys=NULL, *vals=NULL;
3427 PyObject *key, *val, *key2, *val2;
3428 char *p, *k, *v;
3429 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003430
Victor Stinner8c62be82010-05-06 00:08:46 +00003431 i = PyMapping_Size(env);
3432 if (i < 0)
3433 return NULL;
3434 envlist = PyMem_NEW(char *, i + 1);
3435 if (envlist == NULL) {
3436 PyErr_NoMemory();
3437 return NULL;
3438 }
3439 envc = 0;
3440 keys = PyMapping_Keys(env);
3441 vals = PyMapping_Values(env);
3442 if (!keys || !vals)
3443 goto error;
3444 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3445 PyErr_Format(PyExc_TypeError,
3446 "env.keys() or env.values() is not a list");
3447 goto error;
3448 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003449
Victor Stinner8c62be82010-05-06 00:08:46 +00003450 for (pos = 0; pos < i; pos++) {
3451 key = PyList_GetItem(keys, pos);
3452 val = PyList_GetItem(vals, pos);
3453 if (!key || !val)
3454 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003455
Victor Stinner8c62be82010-05-06 00:08:46 +00003456 if (PyUnicode_FSConverter(key, &key2) == 0)
3457 goto error;
3458 if (PyUnicode_FSConverter(val, &val2) == 0) {
3459 Py_DECREF(key2);
3460 goto error;
3461 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003462
3463#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003464 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3465 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
Victor Stinner13bb71c2010-04-23 21:41:56 +00003466#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003467 k = PyBytes_AsString(key2);
3468 v = PyBytes_AsString(val2);
3469 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003470
Victor Stinner8c62be82010-05-06 00:08:46 +00003471 p = PyMem_NEW(char, len);
3472 if (p == NULL) {
3473 PyErr_NoMemory();
3474 Py_DECREF(key2);
3475 Py_DECREF(val2);
3476 goto error;
3477 }
3478 PyOS_snprintf(p, len, "%s=%s", k, v);
3479 envlist[envc++] = p;
3480 Py_DECREF(key2);
3481 Py_DECREF(val2);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003482#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00003483 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00003484#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003485 }
3486 Py_DECREF(vals);
3487 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00003488
Victor Stinner8c62be82010-05-06 00:08:46 +00003489 envlist[envc] = 0;
3490 *envc_ptr = envc;
3491 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003492
3493error:
Victor Stinner8c62be82010-05-06 00:08:46 +00003494 Py_XDECREF(keys);
3495 Py_XDECREF(vals);
3496 while (--envc >= 0)
3497 PyMem_DEL(envlist[envc]);
3498 PyMem_DEL(envlist);
3499 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00003500}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003501
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003502PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003503"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003504Execute a path with arguments and environment, replacing current process.\n\
3505\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003506 path: path of executable file\n\
3507 args: tuple or list of arguments\n\
3508 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003509
Barry Warsaw53699e91996-12-10 23:23:01 +00003510static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003511posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003512{
Victor Stinner8c62be82010-05-06 00:08:46 +00003513 PyObject *opath;
3514 char *path;
3515 PyObject *argv, *env;
3516 char **argvlist;
3517 char **envlist;
3518 Py_ssize_t i, argc, envc;
3519 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3520 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003521
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 /* execve has three arguments: (path, argv, env), where
3523 argv is a list or tuple of strings and env is a dictionary
3524 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003525
Victor Stinner8c62be82010-05-06 00:08:46 +00003526 if (!PyArg_ParseTuple(args, "O&OO:execve",
3527 PyUnicode_FSConverter,
3528 &opath, &argv, &env))
3529 return NULL;
3530 path = PyBytes_AsString(opath);
3531 if (PyList_Check(argv)) {
3532 argc = PyList_Size(argv);
3533 getitem = PyList_GetItem;
3534 }
3535 else if (PyTuple_Check(argv)) {
3536 argc = PyTuple_Size(argv);
3537 getitem = PyTuple_GetItem;
3538 }
3539 else {
3540 PyErr_SetString(PyExc_TypeError,
3541 "execve() arg 2 must be a tuple or list");
3542 goto fail_0;
3543 }
3544 if (!PyMapping_Check(env)) {
3545 PyErr_SetString(PyExc_TypeError,
3546 "execve() arg 3 must be a mapping object");
3547 goto fail_0;
3548 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003549
Victor Stinner8c62be82010-05-06 00:08:46 +00003550 argvlist = PyMem_NEW(char *, argc+1);
3551 if (argvlist == NULL) {
3552 PyErr_NoMemory();
3553 goto fail_0;
3554 }
3555 for (i = 0; i < argc; i++) {
3556 if (!fsconvert_strdup((*getitem)(argv, i),
3557 &argvlist[i]))
3558 {
3559 lastarg = i;
3560 goto fail_1;
3561 }
3562 }
3563 lastarg = argc;
3564 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003565
Victor Stinner8c62be82010-05-06 00:08:46 +00003566 envlist = parse_envlist(env, &envc);
3567 if (envlist == NULL)
3568 goto fail_1;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003569
Victor Stinner8c62be82010-05-06 00:08:46 +00003570 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003571
Victor Stinner8c62be82010-05-06 00:08:46 +00003572 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003573
Victor Stinner8c62be82010-05-06 00:08:46 +00003574 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003575
Victor Stinner8c62be82010-05-06 00:08:46 +00003576 while (--envc >= 0)
3577 PyMem_DEL(envlist[envc]);
3578 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003579 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003580 free_string_array(argvlist, lastarg);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003581 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003582 Py_DECREF(opath);
3583 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003584}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003585#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003586
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003587
Guido van Rossuma1065681999-01-25 23:20:23 +00003588#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003589PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003590"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003591Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003592\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003593 mode: mode of process creation\n\
3594 path: path of executable file\n\
3595 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003596
3597static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003598posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003599{
Victor Stinner8c62be82010-05-06 00:08:46 +00003600 PyObject *opath;
3601 char *path;
3602 PyObject *argv;
3603 char **argvlist;
3604 int mode, i;
3605 Py_ssize_t argc;
3606 Py_intptr_t spawnval;
3607 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003608
Victor Stinner8c62be82010-05-06 00:08:46 +00003609 /* spawnv has three arguments: (mode, path, argv), where
3610 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003611
Victor Stinner8c62be82010-05-06 00:08:46 +00003612 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3613 PyUnicode_FSConverter,
3614 &opath, &argv))
3615 return NULL;
3616 path = PyBytes_AsString(opath);
3617 if (PyList_Check(argv)) {
3618 argc = PyList_Size(argv);
3619 getitem = PyList_GetItem;
3620 }
3621 else if (PyTuple_Check(argv)) {
3622 argc = PyTuple_Size(argv);
3623 getitem = PyTuple_GetItem;
3624 }
3625 else {
3626 PyErr_SetString(PyExc_TypeError,
3627 "spawnv() arg 2 must be a tuple or list");
3628 Py_DECREF(opath);
3629 return NULL;
3630 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003631
Victor Stinner8c62be82010-05-06 00:08:46 +00003632 argvlist = PyMem_NEW(char *, argc+1);
3633 if (argvlist == NULL) {
3634 Py_DECREF(opath);
3635 return PyErr_NoMemory();
3636 }
3637 for (i = 0; i < argc; i++) {
3638 if (!fsconvert_strdup((*getitem)(argv, i),
3639 &argvlist[i])) {
3640 free_string_array(argvlist, i);
3641 PyErr_SetString(
3642 PyExc_TypeError,
3643 "spawnv() arg 2 must contain only strings");
3644 Py_DECREF(opath);
3645 return NULL;
3646 }
3647 }
3648 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003649
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003650#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003651 Py_BEGIN_ALLOW_THREADS
3652 spawnval = spawnv(mode, path, argvlist);
3653 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003654#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003655 if (mode == _OLD_P_OVERLAY)
3656 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003657
Victor Stinner8c62be82010-05-06 00:08:46 +00003658 Py_BEGIN_ALLOW_THREADS
3659 spawnval = _spawnv(mode, path, argvlist);
3660 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003661#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003662
Victor Stinner8c62be82010-05-06 00:08:46 +00003663 free_string_array(argvlist, argc);
3664 Py_DECREF(opath);
Guido van Rossuma1065681999-01-25 23:20:23 +00003665
Victor Stinner8c62be82010-05-06 00:08:46 +00003666 if (spawnval == -1)
3667 return posix_error();
3668 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003669#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003670 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003671#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003672 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003673#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003674}
3675
3676
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003677PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003678"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003679Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003680\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003681 mode: mode of process creation\n\
3682 path: path of executable file\n\
3683 args: tuple or list of arguments\n\
3684 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003685
3686static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003687posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003688{
Victor Stinner8c62be82010-05-06 00:08:46 +00003689 PyObject *opath;
3690 char *path;
3691 PyObject *argv, *env;
3692 char **argvlist;
3693 char **envlist;
3694 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003695 int mode;
3696 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003697 Py_intptr_t spawnval;
3698 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3699 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003700
Victor Stinner8c62be82010-05-06 00:08:46 +00003701 /* spawnve has four arguments: (mode, path, argv, env), where
3702 argv is a list or tuple of strings and env is a dictionary
3703 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003704
Victor Stinner8c62be82010-05-06 00:08:46 +00003705 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3706 PyUnicode_FSConverter,
3707 &opath, &argv, &env))
3708 return NULL;
3709 path = PyBytes_AsString(opath);
3710 if (PyList_Check(argv)) {
3711 argc = PyList_Size(argv);
3712 getitem = PyList_GetItem;
3713 }
3714 else if (PyTuple_Check(argv)) {
3715 argc = PyTuple_Size(argv);
3716 getitem = PyTuple_GetItem;
3717 }
3718 else {
3719 PyErr_SetString(PyExc_TypeError,
3720 "spawnve() arg 2 must be a tuple or list");
3721 goto fail_0;
3722 }
3723 if (!PyMapping_Check(env)) {
3724 PyErr_SetString(PyExc_TypeError,
3725 "spawnve() arg 3 must be a mapping object");
3726 goto fail_0;
3727 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003728
Victor Stinner8c62be82010-05-06 00:08:46 +00003729 argvlist = PyMem_NEW(char *, argc+1);
3730 if (argvlist == NULL) {
3731 PyErr_NoMemory();
3732 goto fail_0;
3733 }
3734 for (i = 0; i < argc; i++) {
3735 if (!fsconvert_strdup((*getitem)(argv, i),
3736 &argvlist[i]))
3737 {
3738 lastarg = i;
3739 goto fail_1;
3740 }
3741 }
3742 lastarg = argc;
3743 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003744
Victor Stinner8c62be82010-05-06 00:08:46 +00003745 envlist = parse_envlist(env, &envc);
3746 if (envlist == NULL)
3747 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003748
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003749#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003750 Py_BEGIN_ALLOW_THREADS
3751 spawnval = spawnve(mode, path, argvlist, envlist);
3752 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003753#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003754 if (mode == _OLD_P_OVERLAY)
3755 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003756
Victor Stinner8c62be82010-05-06 00:08:46 +00003757 Py_BEGIN_ALLOW_THREADS
3758 spawnval = _spawnve(mode, path, argvlist, envlist);
3759 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003760#endif
Tim Peters25059d32001-12-07 20:35:43 +00003761
Victor Stinner8c62be82010-05-06 00:08:46 +00003762 if (spawnval == -1)
3763 (void) posix_error();
3764 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003765#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinner8c62be82010-05-06 00:08:46 +00003766 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003767#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003768 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003769#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003770
Victor Stinner8c62be82010-05-06 00:08:46 +00003771 while (--envc >= 0)
3772 PyMem_DEL(envlist[envc]);
3773 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003774 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003775 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003776 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003777 Py_DECREF(opath);
3778 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003779}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003780
3781/* OS/2 supports spawnvp & spawnvpe natively */
3782#if defined(PYOS_OS2)
3783PyDoc_STRVAR(posix_spawnvp__doc__,
3784"spawnvp(mode, file, args)\n\n\
3785Execute the program 'file' in a new process, using the environment\n\
3786search path to find the file.\n\
3787\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003788 mode: mode of process creation\n\
3789 file: executable file name\n\
3790 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003791
3792static PyObject *
3793posix_spawnvp(PyObject *self, PyObject *args)
3794{
Victor Stinner8c62be82010-05-06 00:08:46 +00003795 PyObject *opath;
3796 char *path;
3797 PyObject *argv;
3798 char **argvlist;
3799 int mode, i, argc;
3800 Py_intptr_t spawnval;
3801 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003802
Victor Stinner8c62be82010-05-06 00:08:46 +00003803 /* spawnvp has three arguments: (mode, path, argv), where
3804 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003805
Victor Stinner8c62be82010-05-06 00:08:46 +00003806 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3807 PyUnicode_FSConverter,
3808 &opath, &argv))
3809 return NULL;
3810 path = PyBytes_AsString(opath);
3811 if (PyList_Check(argv)) {
3812 argc = PyList_Size(argv);
3813 getitem = PyList_GetItem;
3814 }
3815 else if (PyTuple_Check(argv)) {
3816 argc = PyTuple_Size(argv);
3817 getitem = PyTuple_GetItem;
3818 }
3819 else {
3820 PyErr_SetString(PyExc_TypeError,
3821 "spawnvp() arg 2 must be a tuple or list");
3822 Py_DECREF(opath);
3823 return NULL;
3824 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003825
Victor Stinner8c62be82010-05-06 00:08:46 +00003826 argvlist = PyMem_NEW(char *, argc+1);
3827 if (argvlist == NULL) {
3828 Py_DECREF(opath);
3829 return PyErr_NoMemory();
3830 }
3831 for (i = 0; i < argc; i++) {
3832 if (!fsconvert_strdup((*getitem)(argv, i),
3833 &argvlist[i])) {
3834 free_string_array(argvlist, i);
3835 PyErr_SetString(
3836 PyExc_TypeError,
3837 "spawnvp() arg 2 must contain only strings");
3838 Py_DECREF(opath);
3839 return NULL;
3840 }
3841 }
3842 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003843
Victor Stinner8c62be82010-05-06 00:08:46 +00003844 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003845#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003846 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003847#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003848 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003849#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003850 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003851
Victor Stinner8c62be82010-05-06 00:08:46 +00003852 free_string_array(argvlist, argc);
3853 Py_DECREF(opath);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003854
Victor Stinner8c62be82010-05-06 00:08:46 +00003855 if (spawnval == -1)
3856 return posix_error();
3857 else
3858 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003859}
3860
3861
3862PyDoc_STRVAR(posix_spawnvpe__doc__,
3863"spawnvpe(mode, file, args, env)\n\n\
3864Execute the program 'file' in a new process, using the environment\n\
3865search path to find the file.\n\
3866\n\
Victor Stinner8c62be82010-05-06 00:08:46 +00003867 mode: mode of process creation\n\
3868 file: executable file name\n\
3869 args: tuple or list of arguments\n\
3870 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003871
3872static PyObject *
3873posix_spawnvpe(PyObject *self, PyObject *args)
3874{
Victor Stinner8c62be82010-05-06 00:08:46 +00003875 PyObject *opath
3876 char *path;
3877 PyObject *argv, *env;
3878 char **argvlist;
3879 char **envlist;
3880 PyObject *res=NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00003881 int mode;
3882 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00003883 Py_intptr_t spawnval;
3884 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3885 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003886
Victor Stinner8c62be82010-05-06 00:08:46 +00003887 /* spawnvpe has four arguments: (mode, path, argv, env), where
3888 argv is a list or tuple of strings and env is a dictionary
3889 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003890
Victor Stinner8c62be82010-05-06 00:08:46 +00003891 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3892 PyUnicode_FSConverter,
3893 &opath, &argv, &env))
3894 return NULL;
3895 path = PyBytes_AsString(opath);
3896 if (PyList_Check(argv)) {
3897 argc = PyList_Size(argv);
3898 getitem = PyList_GetItem;
3899 }
3900 else if (PyTuple_Check(argv)) {
3901 argc = PyTuple_Size(argv);
3902 getitem = PyTuple_GetItem;
3903 }
3904 else {
3905 PyErr_SetString(PyExc_TypeError,
3906 "spawnvpe() arg 2 must be a tuple or list");
3907 goto fail_0;
3908 }
3909 if (!PyMapping_Check(env)) {
3910 PyErr_SetString(PyExc_TypeError,
3911 "spawnvpe() arg 3 must be a mapping object");
3912 goto fail_0;
3913 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003914
Victor Stinner8c62be82010-05-06 00:08:46 +00003915 argvlist = PyMem_NEW(char *, argc+1);
3916 if (argvlist == NULL) {
3917 PyErr_NoMemory();
3918 goto fail_0;
3919 }
3920 for (i = 0; i < argc; i++) {
3921 if (!fsconvert_strdup((*getitem)(argv, i),
3922 &argvlist[i]))
3923 {
3924 lastarg = i;
3925 goto fail_1;
3926 }
3927 }
3928 lastarg = argc;
3929 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003930
Victor Stinner8c62be82010-05-06 00:08:46 +00003931 envlist = parse_envlist(env, &envc);
3932 if (envlist == NULL)
3933 goto fail_1;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003934
Victor Stinner8c62be82010-05-06 00:08:46 +00003935 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003936#if defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00003937 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003938#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003939 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003940#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003941 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003942
Victor Stinner8c62be82010-05-06 00:08:46 +00003943 if (spawnval == -1)
3944 (void) posix_error();
3945 else
3946 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003947
Victor Stinner8c62be82010-05-06 00:08:46 +00003948 while (--envc >= 0)
3949 PyMem_DEL(envlist[envc]);
3950 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003951 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00003952 free_string_array(argvlist, lastarg);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003953 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00003954 Py_DECREF(opath);
3955 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003956}
3957#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003958#endif /* HAVE_SPAWNV */
3959
3960
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003961#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003962PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003963"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003964Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3965\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003966Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003967
3968static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003969posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003970{
Victor Stinner8c62be82010-05-06 00:08:46 +00003971 pid_t pid;
3972 int result = 0;
3973 _PyImport_AcquireLock();
3974 pid = fork1();
3975 if (pid == 0) {
3976 /* child: this clobbers and resets the import lock. */
3977 PyOS_AfterFork();
3978 } else {
3979 /* parent: release the import lock. */
3980 result = _PyImport_ReleaseLock();
3981 }
3982 if (pid == -1)
3983 return posix_error();
3984 if (result < 0) {
3985 /* Don't clobber the OSError if the fork failed. */
3986 PyErr_SetString(PyExc_RuntimeError,
3987 "not holding the import lock");
3988 return NULL;
3989 }
3990 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003991}
3992#endif
3993
3994
Guido van Rossumad0ee831995-03-01 10:34:45 +00003995#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003996PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003997"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003998Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003999Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004000
Barry Warsaw53699e91996-12-10 23:23:01 +00004001static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004002posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004003{
Victor Stinner8c62be82010-05-06 00:08:46 +00004004 pid_t pid;
4005 int result = 0;
4006 _PyImport_AcquireLock();
4007 pid = fork();
4008 if (pid == 0) {
4009 /* child: this clobbers and resets the import lock. */
4010 PyOS_AfterFork();
4011 } else {
4012 /* parent: release the import lock. */
4013 result = _PyImport_ReleaseLock();
4014 }
4015 if (pid == -1)
4016 return posix_error();
4017 if (result < 0) {
4018 /* Don't clobber the OSError if the fork failed. */
4019 PyErr_SetString(PyExc_RuntimeError,
4020 "not holding the import lock");
4021 return NULL;
4022 }
4023 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00004024}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004025#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004026
Neal Norwitzb59798b2003-03-21 01:43:31 +00004027/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00004028/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
4029#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00004030#define DEV_PTY_FILE "/dev/ptc"
4031#define HAVE_DEV_PTMX
4032#else
4033#define DEV_PTY_FILE "/dev/ptmx"
4034#endif
4035
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004036#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004037#ifdef HAVE_PTY_H
4038#include <pty.h>
4039#else
4040#ifdef HAVE_LIBUTIL_H
4041#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00004042#else
4043#ifdef HAVE_UTIL_H
4044#include <util.h>
4045#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004046#endif /* HAVE_LIBUTIL_H */
4047#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00004048#ifdef HAVE_STROPTS_H
4049#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004050#endif
4051#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004052
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004053#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004054PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004055"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004056Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004057
4058static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004059posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004060{
Victor Stinner8c62be82010-05-06 00:08:46 +00004061 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004062#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004063 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00004064#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004065#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004066 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004067#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00004068 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004069#endif
4070#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00004071
Thomas Wouters70c21a12000-07-14 14:28:33 +00004072#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00004073 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
4074 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004075#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004076 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
4077 if (slave_name == NULL)
4078 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00004079
Victor Stinner8c62be82010-05-06 00:08:46 +00004080 slave_fd = open(slave_name, O_RDWR);
4081 if (slave_fd < 0)
4082 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004083#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004084 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
4085 if (master_fd < 0)
4086 return posix_error();
4087 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
4088 /* change permission of slave */
4089 if (grantpt(master_fd) < 0) {
4090 PyOS_setsig(SIGCHLD, sig_saved);
4091 return posix_error();
4092 }
4093 /* unlock slave */
4094 if (unlockpt(master_fd) < 0) {
4095 PyOS_setsig(SIGCHLD, sig_saved);
4096 return posix_error();
4097 }
4098 PyOS_setsig(SIGCHLD, sig_saved);
4099 slave_name = ptsname(master_fd); /* get name of slave */
4100 if (slave_name == NULL)
4101 return posix_error();
4102 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
4103 if (slave_fd < 0)
4104 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00004105#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00004106 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
4107 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00004108#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00004109 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00004110#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004111#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004112#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004113
Victor Stinner8c62be82010-05-06 00:08:46 +00004114 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004115
Fred Drake8cef4cf2000-06-28 16:40:38 +00004116}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004117#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004118
4119#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004120PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004121"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004122Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4123Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004124To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004125
4126static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004127posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004128{
Victor Stinner8c62be82010-05-06 00:08:46 +00004129 int master_fd = -1, result = 0;
4130 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004131
Victor Stinner8c62be82010-05-06 00:08:46 +00004132 _PyImport_AcquireLock();
4133 pid = forkpty(&master_fd, NULL, NULL, NULL);
4134 if (pid == 0) {
4135 /* child: this clobbers and resets the import lock. */
4136 PyOS_AfterFork();
4137 } else {
4138 /* parent: release the import lock. */
4139 result = _PyImport_ReleaseLock();
4140 }
4141 if (pid == -1)
4142 return posix_error();
4143 if (result < 0) {
4144 /* Don't clobber the OSError if the fork failed. */
4145 PyErr_SetString(PyExc_RuntimeError,
4146 "not holding the import lock");
4147 return NULL;
4148 }
4149 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004150}
4151#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004152
Guido van Rossumad0ee831995-03-01 10:34:45 +00004153#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004154PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004155"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004156Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004157
Barry Warsaw53699e91996-12-10 23:23:01 +00004158static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004159posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004160{
Victor Stinner8c62be82010-05-06 00:08:46 +00004161 return PyLong_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004162}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004163#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004164
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004165
Guido van Rossumad0ee831995-03-01 10:34:45 +00004166#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004167PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004168"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004169Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004170
Barry Warsaw53699e91996-12-10 23:23:01 +00004171static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004172posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004173{
Victor Stinner8c62be82010-05-06 00:08:46 +00004174 return PyLong_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004175}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004176#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004177
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004178
Guido van Rossumad0ee831995-03-01 10:34:45 +00004179#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004180PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004181"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004182Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004183
Barry Warsaw53699e91996-12-10 23:23:01 +00004184static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004185posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004186{
Victor Stinner8c62be82010-05-06 00:08:46 +00004187 return PyLong_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004188}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004189#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004190
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004191
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004192PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004193"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004194Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004195
Barry Warsaw53699e91996-12-10 23:23:01 +00004196static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004197posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004198{
Victor Stinner8c62be82010-05-06 00:08:46 +00004199 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004200}
4201
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004202
Fred Drakec9680921999-12-13 16:37:25 +00004203#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004204PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004205"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004206Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004207
4208static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004209posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004210{
4211 PyObject *result = NULL;
4212
Fred Drakec9680921999-12-13 16:37:25 +00004213#ifdef NGROUPS_MAX
4214#define MAX_GROUPS NGROUPS_MAX
4215#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004216 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004217#define MAX_GROUPS 64
4218#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004219 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004220
4221 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
4222 * This is a helper variable to store the intermediate result when
4223 * that happens.
4224 *
4225 * To keep the code readable the OSX behaviour is unconditional,
4226 * according to the POSIX spec this should be safe on all unix-y
4227 * systems.
4228 */
4229 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00004230 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004231
Victor Stinner8c62be82010-05-06 00:08:46 +00004232 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004233 if (n < 0) {
4234 if (errno == EINVAL) {
4235 n = getgroups(0, NULL);
4236 if (n == -1) {
4237 return posix_error();
4238 }
4239 if (n == 0) {
4240 /* Avoid malloc(0) */
4241 alt_grouplist = grouplist;
4242 } else {
4243 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4244 if (alt_grouplist == NULL) {
4245 errno = EINVAL;
4246 return posix_error();
4247 }
4248 n = getgroups(n, alt_grouplist);
4249 if (n == -1) {
4250 PyMem_Free(alt_grouplist);
4251 return posix_error();
4252 }
4253 }
4254 } else {
4255 return posix_error();
4256 }
4257 }
4258 result = PyList_New(n);
4259 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004260 int i;
4261 for (i = 0; i < n; ++i) {
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004262 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00004263 if (o == NULL) {
4264 Py_DECREF(result);
4265 result = NULL;
4266 break;
Fred Drakec9680921999-12-13 16:37:25 +00004267 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004268 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004269 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00004270 }
4271
4272 if (alt_grouplist != grouplist) {
4273 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00004274 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004275
Fred Drakec9680921999-12-13 16:37:25 +00004276 return result;
4277}
4278#endif
4279
Antoine Pitroub7572f02009-12-02 20:46:48 +00004280#ifdef HAVE_INITGROUPS
4281PyDoc_STRVAR(posix_initgroups__doc__,
4282"initgroups(username, gid) -> None\n\n\
4283Call the system initgroups() to initialize the group access list with all of\n\
4284the groups of which the specified username is a member, plus the specified\n\
4285group id.");
4286
4287static PyObject *
4288posix_initgroups(PyObject *self, PyObject *args)
4289{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004290 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00004291 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004292 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00004293 long gid;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004294
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004295 if (!PyArg_ParseTuple(args, "O&l:initgroups",
4296 PyUnicode_FSConverter, &oname, &gid))
Victor Stinner8c62be82010-05-06 00:08:46 +00004297 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004298 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004299
Victor Stinner61ec5dc2010-08-15 09:22:44 +00004300 res = initgroups(username, (gid_t) gid);
4301 Py_DECREF(oname);
4302 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00004303 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00004304
Victor Stinner8c62be82010-05-06 00:08:46 +00004305 Py_INCREF(Py_None);
4306 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00004307}
4308#endif
4309
Martin v. Löwis606edc12002-06-13 21:09:11 +00004310#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004311PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004312"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004313Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004314
4315static PyObject *
4316posix_getpgid(PyObject *self, PyObject *args)
4317{
Victor Stinner8c62be82010-05-06 00:08:46 +00004318 pid_t pid, pgid;
4319 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid))
4320 return NULL;
4321 pgid = getpgid(pid);
4322 if (pgid < 0)
4323 return posix_error();
4324 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004325}
4326#endif /* HAVE_GETPGID */
4327
4328
Guido van Rossumb6775db1994-08-01 11:34:53 +00004329#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004330PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004331"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004332Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004333
Barry Warsaw53699e91996-12-10 23:23:01 +00004334static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004335posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004336{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004337#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004338 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004339#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004340 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004341#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004342}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004343#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004344
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004345
Guido van Rossumb6775db1994-08-01 11:34:53 +00004346#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004347PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004348"setpgrp()\n\n\
Senthil Kumaran684760a2010-06-17 16:48:06 +00004349Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004350
Barry Warsaw53699e91996-12-10 23:23:01 +00004351static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004352posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004353{
Guido van Rossum64933891994-10-20 21:56:42 +00004354#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00004355 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004356#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004357 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004358#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00004359 return posix_error();
4360 Py_INCREF(Py_None);
4361 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004362}
4363
Guido van Rossumb6775db1994-08-01 11:34:53 +00004364#endif /* HAVE_SETPGRP */
4365
Guido van Rossumad0ee831995-03-01 10:34:45 +00004366#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004367
4368#ifdef MS_WINDOWS
4369#include <tlhelp32.h>
4370
4371static PyObject*
4372win32_getppid()
4373{
4374 HANDLE snapshot;
4375 pid_t mypid;
4376 PyObject* result = NULL;
4377 BOOL have_record;
4378 PROCESSENTRY32 pe;
4379
4380 mypid = getpid(); /* This function never fails */
4381
4382 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
4383 if (snapshot == INVALID_HANDLE_VALUE)
4384 return PyErr_SetFromWindowsErr(GetLastError());
4385
4386 pe.dwSize = sizeof(pe);
4387 have_record = Process32First(snapshot, &pe);
4388 while (have_record) {
4389 if (mypid == (pid_t)pe.th32ProcessID) {
4390 /* We could cache the ulong value in a static variable. */
4391 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
4392 break;
4393 }
4394
4395 have_record = Process32Next(snapshot, &pe);
4396 }
4397
4398 /* If our loop exits and our pid was not found (result will be NULL)
4399 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
4400 * error anyway, so let's raise it. */
4401 if (!result)
4402 result = PyErr_SetFromWindowsErr(GetLastError());
4403
4404 CloseHandle(snapshot);
4405
4406 return result;
4407}
4408#endif /*MS_WINDOWS*/
4409
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004410PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004411"getppid() -> ppid\n\n\
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004412Return the parent's process id. If the parent process has already exited,\n\
4413Windows machines will still return its id; others systems will return the id\n\
4414of the 'init' process (1).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004415
Barry Warsaw53699e91996-12-10 23:23:01 +00004416static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004417posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004418{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004419#ifdef MS_WINDOWS
4420 return win32_getppid();
4421#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004422 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00004423#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00004424}
4425#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004426
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004427
Fred Drake12c6e2d1999-12-14 21:25:03 +00004428#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004429PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004430"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004431Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004432
4433static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004434posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004435{
Victor Stinner8c62be82010-05-06 00:08:46 +00004436 PyObject *result = NULL;
4437 char *name;
4438 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004439
Victor Stinner8c62be82010-05-06 00:08:46 +00004440 errno = 0;
4441 name = getlogin();
4442 if (name == NULL) {
4443 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00004444 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004445 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004446 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00004447 }
4448 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00004449 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00004450 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004451
Fred Drake12c6e2d1999-12-14 21:25:03 +00004452 return result;
4453}
4454#endif
4455
Guido van Rossumad0ee831995-03-01 10:34:45 +00004456#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004457PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004458"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004459Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004460
Barry Warsaw53699e91996-12-10 23:23:01 +00004461static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004462posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004463{
Victor Stinner8c62be82010-05-06 00:08:46 +00004464 return PyLong_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004465}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004466#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004468
Guido van Rossumad0ee831995-03-01 10:34:45 +00004469#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004470PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004471"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004472Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004473
Barry Warsaw53699e91996-12-10 23:23:01 +00004474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004475posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004476{
Victor Stinner8c62be82010-05-06 00:08:46 +00004477 pid_t pid;
4478 int sig;
4479 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig))
4480 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004481#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004482 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4483 APIRET rc;
4484 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004485 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004486
4487 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4488 APIRET rc;
4489 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004490 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004491
4492 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004493 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004494#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004495 if (kill(pid, sig) == -1)
4496 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004497#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004498 Py_INCREF(Py_None);
4499 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004500}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004501#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004502
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004503#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004504PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004505"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004506Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004507
4508static PyObject *
4509posix_killpg(PyObject *self, PyObject *args)
4510{
Victor Stinner8c62be82010-05-06 00:08:46 +00004511 int sig;
4512 pid_t pgid;
4513 /* XXX some man pages make the `pgid` parameter an int, others
4514 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4515 take the same type. Moreover, pid_t is always at least as wide as
4516 int (else compilation of this module fails), which is safe. */
4517 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig))
4518 return NULL;
4519 if (killpg(pgid, sig) == -1)
4520 return posix_error();
4521 Py_INCREF(Py_None);
4522 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004523}
4524#endif
4525
Brian Curtineb24d742010-04-12 17:16:38 +00004526#ifdef MS_WINDOWS
4527PyDoc_STRVAR(win32_kill__doc__,
4528"kill(pid, sig)\n\n\
4529Kill a process with a signal.");
4530
4531static PyObject *
4532win32_kill(PyObject *self, PyObject *args)
4533{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00004534 PyObject *result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004535 DWORD pid, sig, err;
4536 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00004537
Victor Stinner8c62be82010-05-06 00:08:46 +00004538 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4539 return NULL;
Brian Curtineb24d742010-04-12 17:16:38 +00004540
Victor Stinner8c62be82010-05-06 00:08:46 +00004541 /* Console processes which share a common console can be sent CTRL+C or
4542 CTRL+BREAK events, provided they handle said events. */
4543 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4544 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4545 err = GetLastError();
4546 PyErr_SetFromWindowsErr(err);
4547 }
4548 else
4549 Py_RETURN_NONE;
4550 }
Brian Curtineb24d742010-04-12 17:16:38 +00004551
Victor Stinner8c62be82010-05-06 00:08:46 +00004552 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4553 attempt to open and terminate the process. */
4554 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4555 if (handle == NULL) {
4556 err = GetLastError();
4557 return PyErr_SetFromWindowsErr(err);
4558 }
Brian Curtineb24d742010-04-12 17:16:38 +00004559
Victor Stinner8c62be82010-05-06 00:08:46 +00004560 if (TerminateProcess(handle, sig) == 0) {
4561 err = GetLastError();
4562 result = PyErr_SetFromWindowsErr(err);
4563 } else {
4564 Py_INCREF(Py_None);
4565 result = Py_None;
4566 }
Brian Curtineb24d742010-04-12 17:16:38 +00004567
Victor Stinner8c62be82010-05-06 00:08:46 +00004568 CloseHandle(handle);
4569 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00004570}
4571#endif /* MS_WINDOWS */
4572
Guido van Rossumc0125471996-06-28 18:55:32 +00004573#ifdef HAVE_PLOCK
4574
4575#ifdef HAVE_SYS_LOCK_H
4576#include <sys/lock.h>
4577#endif
4578
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004579PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004580"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004581Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004582
Barry Warsaw53699e91996-12-10 23:23:01 +00004583static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004584posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004585{
Victor Stinner8c62be82010-05-06 00:08:46 +00004586 int op;
4587 if (!PyArg_ParseTuple(args, "i:plock", &op))
4588 return NULL;
4589 if (plock(op) == -1)
4590 return posix_error();
4591 Py_INCREF(Py_None);
4592 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004593}
4594#endif
4595
Guido van Rossumb6775db1994-08-01 11:34:53 +00004596#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004597PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004598"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004599Set the current process's user id.");
4600
Barry Warsaw53699e91996-12-10 23:23:01 +00004601static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004602posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004603{
Victor Stinner8c62be82010-05-06 00:08:46 +00004604 long uid_arg;
4605 uid_t uid;
4606 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4607 return NULL;
4608 uid = uid_arg;
4609 if (uid != uid_arg) {
4610 PyErr_SetString(PyExc_OverflowError, "user id too big");
4611 return NULL;
4612 }
4613 if (setuid(uid) < 0)
4614 return posix_error();
4615 Py_INCREF(Py_None);
4616 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004617}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004618#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004619
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004620
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004621#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004622PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004623"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004624Set the current process's effective user id.");
4625
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004626static PyObject *
4627posix_seteuid (PyObject *self, PyObject *args)
4628{
Victor Stinner8c62be82010-05-06 00:08:46 +00004629 long euid_arg;
4630 uid_t euid;
4631 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4632 return NULL;
4633 euid = euid_arg;
4634 if (euid != euid_arg) {
4635 PyErr_SetString(PyExc_OverflowError, "user id too big");
4636 return NULL;
4637 }
4638 if (seteuid(euid) < 0) {
4639 return posix_error();
4640 } else {
4641 Py_INCREF(Py_None);
4642 return Py_None;
4643 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004644}
4645#endif /* HAVE_SETEUID */
4646
4647#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004648PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004649"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004650Set the current process's effective group id.");
4651
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004652static PyObject *
4653posix_setegid (PyObject *self, PyObject *args)
4654{
Victor Stinner8c62be82010-05-06 00:08:46 +00004655 long egid_arg;
4656 gid_t egid;
4657 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4658 return NULL;
4659 egid = egid_arg;
4660 if (egid != egid_arg) {
4661 PyErr_SetString(PyExc_OverflowError, "group id too big");
4662 return NULL;
4663 }
4664 if (setegid(egid) < 0) {
4665 return posix_error();
4666 } else {
4667 Py_INCREF(Py_None);
4668 return Py_None;
4669 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004670}
4671#endif /* HAVE_SETEGID */
4672
4673#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004674PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004675"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004676Set the current process's real and effective user ids.");
4677
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004678static PyObject *
4679posix_setreuid (PyObject *self, PyObject *args)
4680{
Victor Stinner8c62be82010-05-06 00:08:46 +00004681 long ruid_arg, euid_arg;
4682 uid_t ruid, euid;
4683 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4684 return NULL;
4685 if (ruid_arg == -1)
4686 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4687 else
4688 ruid = ruid_arg; /* otherwise, assign from our long */
4689 if (euid_arg == -1)
4690 euid = (uid_t)-1;
4691 else
4692 euid = euid_arg;
4693 if ((euid_arg != -1 && euid != euid_arg) ||
4694 (ruid_arg != -1 && ruid != ruid_arg)) {
4695 PyErr_SetString(PyExc_OverflowError, "user id too big");
4696 return NULL;
4697 }
4698 if (setreuid(ruid, euid) < 0) {
4699 return posix_error();
4700 } else {
4701 Py_INCREF(Py_None);
4702 return Py_None;
4703 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004704}
4705#endif /* HAVE_SETREUID */
4706
4707#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004708PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004709"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004710Set the current process's real and effective group ids.");
4711
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004712static PyObject *
4713posix_setregid (PyObject *self, PyObject *args)
4714{
Victor Stinner8c62be82010-05-06 00:08:46 +00004715 long rgid_arg, egid_arg;
4716 gid_t rgid, egid;
4717 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4718 return NULL;
4719 if (rgid_arg == -1)
4720 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4721 else
4722 rgid = rgid_arg; /* otherwise, assign from our long */
4723 if (egid_arg == -1)
4724 egid = (gid_t)-1;
4725 else
4726 egid = egid_arg;
4727 if ((egid_arg != -1 && egid != egid_arg) ||
4728 (rgid_arg != -1 && rgid != rgid_arg)) {
4729 PyErr_SetString(PyExc_OverflowError, "group id too big");
4730 return NULL;
4731 }
4732 if (setregid(rgid, egid) < 0) {
4733 return posix_error();
4734 } else {
4735 Py_INCREF(Py_None);
4736 return Py_None;
4737 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004738}
4739#endif /* HAVE_SETREGID */
4740
Guido van Rossumb6775db1994-08-01 11:34:53 +00004741#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004742PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004743"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004744Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004745
Barry Warsaw53699e91996-12-10 23:23:01 +00004746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004747posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004748{
Victor Stinner8c62be82010-05-06 00:08:46 +00004749 long gid_arg;
4750 gid_t gid;
4751 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4752 return NULL;
4753 gid = gid_arg;
4754 if (gid != gid_arg) {
4755 PyErr_SetString(PyExc_OverflowError, "group id too big");
4756 return NULL;
4757 }
4758 if (setgid(gid) < 0)
4759 return posix_error();
4760 Py_INCREF(Py_None);
4761 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004762}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004763#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004764
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004765#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004766PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004767"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004768Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004769
4770static PyObject *
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00004771posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004772{
Victor Stinner8c62be82010-05-06 00:08:46 +00004773 int i, len;
4774 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004775
Victor Stinner8c62be82010-05-06 00:08:46 +00004776 if (!PySequence_Check(groups)) {
4777 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4778 return NULL;
4779 }
4780 len = PySequence_Size(groups);
4781 if (len > MAX_GROUPS) {
4782 PyErr_SetString(PyExc_ValueError, "too many groups");
4783 return NULL;
4784 }
4785 for(i = 0; i < len; i++) {
4786 PyObject *elem;
4787 elem = PySequence_GetItem(groups, i);
4788 if (!elem)
4789 return NULL;
4790 if (!PyLong_Check(elem)) {
4791 PyErr_SetString(PyExc_TypeError,
4792 "groups must be integers");
4793 Py_DECREF(elem);
4794 return NULL;
4795 } else {
4796 unsigned long x = PyLong_AsUnsignedLong(elem);
4797 if (PyErr_Occurred()) {
4798 PyErr_SetString(PyExc_TypeError,
4799 "group id too big");
4800 Py_DECREF(elem);
4801 return NULL;
4802 }
4803 grouplist[i] = x;
4804 /* read back the value to see if it fitted in gid_t */
4805 if (grouplist[i] != x) {
4806 PyErr_SetString(PyExc_TypeError,
4807 "group id too big");
4808 Py_DECREF(elem);
4809 return NULL;
4810 }
4811 }
4812 Py_DECREF(elem);
4813 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004814
Victor Stinner8c62be82010-05-06 00:08:46 +00004815 if (setgroups(len, grouplist) < 0)
4816 return posix_error();
4817 Py_INCREF(Py_None);
4818 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004819}
4820#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004821
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004822#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4823static PyObject *
Christian Heimes292d3512008-02-03 16:51:08 +00004824wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004825{
Victor Stinner8c62be82010-05-06 00:08:46 +00004826 PyObject *result;
4827 static PyObject *struct_rusage;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004828
Victor Stinner8c62be82010-05-06 00:08:46 +00004829 if (pid == -1)
4830 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004831
Victor Stinner8c62be82010-05-06 00:08:46 +00004832 if (struct_rusage == NULL) {
4833 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4834 if (m == NULL)
4835 return NULL;
4836 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4837 Py_DECREF(m);
4838 if (struct_rusage == NULL)
4839 return NULL;
4840 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004841
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4843 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4844 if (!result)
4845 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004846
4847#ifndef doubletime
4848#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4849#endif
4850
Victor Stinner8c62be82010-05-06 00:08:46 +00004851 PyStructSequence_SET_ITEM(result, 0,
4852 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4853 PyStructSequence_SET_ITEM(result, 1,
4854 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004855#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00004856 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4857 SET_INT(result, 2, ru->ru_maxrss);
4858 SET_INT(result, 3, ru->ru_ixrss);
4859 SET_INT(result, 4, ru->ru_idrss);
4860 SET_INT(result, 5, ru->ru_isrss);
4861 SET_INT(result, 6, ru->ru_minflt);
4862 SET_INT(result, 7, ru->ru_majflt);
4863 SET_INT(result, 8, ru->ru_nswap);
4864 SET_INT(result, 9, ru->ru_inblock);
4865 SET_INT(result, 10, ru->ru_oublock);
4866 SET_INT(result, 11, ru->ru_msgsnd);
4867 SET_INT(result, 12, ru->ru_msgrcv);
4868 SET_INT(result, 13, ru->ru_nsignals);
4869 SET_INT(result, 14, ru->ru_nvcsw);
4870 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004871#undef SET_INT
4872
Victor Stinner8c62be82010-05-06 00:08:46 +00004873 if (PyErr_Occurred()) {
4874 Py_DECREF(result);
4875 return NULL;
4876 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004877
Victor Stinner8c62be82010-05-06 00:08:46 +00004878 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004879}
4880#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4881
4882#ifdef HAVE_WAIT3
4883PyDoc_STRVAR(posix_wait3__doc__,
4884"wait3(options) -> (pid, status, rusage)\n\n\
4885Wait for completion of a child process.");
4886
4887static PyObject *
4888posix_wait3(PyObject *self, PyObject *args)
4889{
Victor Stinner8c62be82010-05-06 00:08:46 +00004890 pid_t pid;
4891 int options;
4892 struct rusage ru;
4893 WAIT_TYPE status;
4894 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004895
Victor Stinner8c62be82010-05-06 00:08:46 +00004896 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4897 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004898
Victor Stinner8c62be82010-05-06 00:08:46 +00004899 Py_BEGIN_ALLOW_THREADS
4900 pid = wait3(&status, options, &ru);
4901 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004902
Victor Stinner8c62be82010-05-06 00:08:46 +00004903 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004904}
4905#endif /* HAVE_WAIT3 */
4906
4907#ifdef HAVE_WAIT4
4908PyDoc_STRVAR(posix_wait4__doc__,
4909"wait4(pid, options) -> (pid, status, rusage)\n\n\
4910Wait for completion of a given child process.");
4911
4912static PyObject *
4913posix_wait4(PyObject *self, PyObject *args)
4914{
Victor Stinner8c62be82010-05-06 00:08:46 +00004915 pid_t pid;
4916 int options;
4917 struct rusage ru;
4918 WAIT_TYPE status;
4919 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004920
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options))
4922 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004923
Victor Stinner8c62be82010-05-06 00:08:46 +00004924 Py_BEGIN_ALLOW_THREADS
4925 pid = wait4(pid, &status, options, &ru);
4926 Py_END_ALLOW_THREADS
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004927
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004929}
4930#endif /* HAVE_WAIT4 */
4931
Guido van Rossumb6775db1994-08-01 11:34:53 +00004932#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004933PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004934"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004935Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004936
Barry Warsaw53699e91996-12-10 23:23:01 +00004937static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004938posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004939{
Victor Stinner8c62be82010-05-06 00:08:46 +00004940 pid_t pid;
4941 int options;
4942 WAIT_TYPE status;
4943 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004944
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4946 return NULL;
4947 Py_BEGIN_ALLOW_THREADS
4948 pid = waitpid(pid, &status, options);
4949 Py_END_ALLOW_THREADS
4950 if (pid == -1)
4951 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004952
Victor Stinner8c62be82010-05-06 00:08:46 +00004953 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00004954}
4955
Tim Petersab034fa2002-02-01 11:27:43 +00004956#elif defined(HAVE_CWAIT)
4957
4958/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004959PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004960"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004961"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004962
4963static PyObject *
4964posix_waitpid(PyObject *self, PyObject *args)
4965{
Victor Stinner8c62be82010-05-06 00:08:46 +00004966 Py_intptr_t pid;
4967 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00004968
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options))
4970 return NULL;
4971 Py_BEGIN_ALLOW_THREADS
4972 pid = _cwait(&status, pid, options);
4973 Py_END_ALLOW_THREADS
4974 if (pid == -1)
4975 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004976
Victor Stinner8c62be82010-05-06 00:08:46 +00004977 /* shift the status left a byte so this is more like the POSIX waitpid */
4978 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00004979}
4980#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004981
Guido van Rossumad0ee831995-03-01 10:34:45 +00004982#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004983PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004984"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004985Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004986
Barry Warsaw53699e91996-12-10 23:23:01 +00004987static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004988posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004989{
Victor Stinner8c62be82010-05-06 00:08:46 +00004990 pid_t pid;
4991 WAIT_TYPE status;
4992 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00004993
Victor Stinner8c62be82010-05-06 00:08:46 +00004994 Py_BEGIN_ALLOW_THREADS
4995 pid = wait(&status);
4996 Py_END_ALLOW_THREADS
4997 if (pid == -1)
4998 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004999
Victor Stinner8c62be82010-05-06 00:08:46 +00005000 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005001}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005002#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005003
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005004
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005005PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005006"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005007Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005008
Barry Warsaw53699e91996-12-10 23:23:01 +00005009static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005010posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005011{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005012#ifdef HAVE_LSTAT
Victor Stinner8c62be82010-05-06 00:08:46 +00005013 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005014#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005015#ifdef MS_WINDOWS
Brian Curtind40e6f72010-07-08 21:39:08 +00005016 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat",
5017 win32_lstat_w);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005018#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005019 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005020#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005021#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005022}
5023
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005024
Guido van Rossumb6775db1994-08-01 11:34:53 +00005025#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005026PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005027"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005028Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005029
Barry Warsaw53699e91996-12-10 23:23:01 +00005030static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005031posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005032{
Victor Stinner8c62be82010-05-06 00:08:46 +00005033 PyObject* v;
5034 char buf[MAXPATHLEN];
5035 PyObject *opath;
5036 char *path;
5037 int n;
5038 int arg_is_unicode = 0;
Thomas Wouters89f507f2006-12-13 04:49:30 +00005039
Victor Stinner8c62be82010-05-06 00:08:46 +00005040 if (!PyArg_ParseTuple(args, "O&:readlink",
5041 PyUnicode_FSConverter, &opath))
5042 return NULL;
5043 path = PyBytes_AsString(opath);
5044 v = PySequence_GetItem(args, 0);
5045 if (v == NULL) {
5046 Py_DECREF(opath);
5047 return NULL;
5048 }
Thomas Wouters89f507f2006-12-13 04:49:30 +00005049
Victor Stinner8c62be82010-05-06 00:08:46 +00005050 if (PyUnicode_Check(v)) {
5051 arg_is_unicode = 1;
5052 }
5053 Py_DECREF(v);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005054
Victor Stinner8c62be82010-05-06 00:08:46 +00005055 Py_BEGIN_ALLOW_THREADS
5056 n = readlink(path, buf, (int) sizeof buf);
5057 Py_END_ALLOW_THREADS
5058 if (n < 0)
5059 return posix_error_with_allocated_filename(opath);
Thomas Wouters89f507f2006-12-13 04:49:30 +00005060
Victor Stinner8c62be82010-05-06 00:08:46 +00005061 Py_DECREF(opath);
Victor Stinnera45598a2010-05-14 16:35:39 +00005062 if (arg_is_unicode)
5063 return PyUnicode_DecodeFSDefaultAndSize(buf, n);
5064 else
5065 return PyBytes_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005066}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005067#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005068
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005069
Guido van Rossumb6775db1994-08-01 11:34:53 +00005070#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005071PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005072"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005073Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005074
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005075static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005076posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005077{
Victor Stinner8c62be82010-05-06 00:08:46 +00005078 return posix_2str(args, "O&O&:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005079}
5080#endif /* HAVE_SYMLINK */
5081
Brian Curtind40e6f72010-07-08 21:39:08 +00005082#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
5083
5084PyDoc_STRVAR(win_readlink__doc__,
5085"readlink(path) -> path\n\n\
5086Return a string representing the path to which the symbolic link points.");
5087
5088/* The following structure was copied from
5089 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required
5090 include doesn't seem to be present in the Windows SDK (at least as included
5091 with Visual Studio Express). */
5092typedef struct _REPARSE_DATA_BUFFER {
5093 ULONG ReparseTag;
5094 USHORT ReparseDataLength;
5095 USHORT Reserved;
5096 union {
5097 struct {
5098 USHORT SubstituteNameOffset;
5099 USHORT SubstituteNameLength;
5100 USHORT PrintNameOffset;
5101 USHORT PrintNameLength;
5102 ULONG Flags;
5103 WCHAR PathBuffer[1];
5104 } SymbolicLinkReparseBuffer;
5105
5106 struct {
5107 USHORT SubstituteNameOffset;
5108 USHORT SubstituteNameLength;
5109 USHORT PrintNameOffset;
5110 USHORT PrintNameLength;
5111 WCHAR PathBuffer[1];
5112 } MountPointReparseBuffer;
5113
5114 struct {
5115 UCHAR DataBuffer[1];
5116 } GenericReparseBuffer;
5117 };
5118} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
5119
Brian Curtin74e45612010-07-09 15:58:59 +00005120#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\
5121 GenericReparseBuffer)
Brian Curtind40e6f72010-07-08 21:39:08 +00005122
5123#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
5124
5125/* Windows readlink implementation */
5126static PyObject *
5127win_readlink(PyObject *self, PyObject *args)
5128{
5129 wchar_t *path;
5130 DWORD n_bytes_returned;
5131 DWORD io_result;
5132 PyObject *result;
5133 HANDLE reparse_point_handle;
5134
5135 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
5136 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
5137 wchar_t *print_name;
5138
5139 if (!PyArg_ParseTuple(args,
5140 "u:readlink",
5141 &path))
5142 return NULL;
5143
5144 /* First get a handle to the reparse point */
5145 Py_BEGIN_ALLOW_THREADS
5146 reparse_point_handle = CreateFileW(
5147 path,
5148 0,
5149 0,
5150 0,
5151 OPEN_EXISTING,
5152 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
5153 0);
5154 Py_END_ALLOW_THREADS
5155
5156 if (reparse_point_handle==INVALID_HANDLE_VALUE)
5157 {
5158 return win32_error_unicode("readlink", path);
5159 }
5160
5161 Py_BEGIN_ALLOW_THREADS
5162 /* New call DeviceIoControl to read the reparse point */
5163 io_result = DeviceIoControl(
5164 reparse_point_handle,
5165 FSCTL_GET_REPARSE_POINT,
5166 0, 0, /* in buffer */
5167 target_buffer, sizeof(target_buffer),
5168 &n_bytes_returned,
5169 0 /* we're not using OVERLAPPED_IO */
5170 );
5171 CloseHandle(reparse_point_handle);
5172 Py_END_ALLOW_THREADS
5173
5174 if (io_result==0)
5175 {
5176 return win32_error_unicode("readlink", path);
5177 }
5178
5179 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
5180 {
5181 PyErr_SetString(PyExc_ValueError,
5182 "not a symbolic link");
5183 return NULL;
5184 }
Brian Curtin74e45612010-07-09 15:58:59 +00005185 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
5186 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
5187
5188 result = PyUnicode_FromWideChar(print_name,
5189 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
Brian Curtind40e6f72010-07-08 21:39:08 +00005190 return result;
5191}
5192
5193#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
5194
5195#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
5196
5197/* Grab CreateSymbolicLinkW dynamically from kernel32 */
5198static int has_CreateSymbolicLinkW = 0;
5199static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD);
5200static int
5201check_CreateSymbolicLinkW()
5202{
5203 HINSTANCE hKernel32;
5204 /* only recheck */
5205 if (has_CreateSymbolicLinkW)
5206 return has_CreateSymbolicLinkW;
5207 hKernel32 = GetModuleHandle("KERNEL32");
Brian Curtin74e45612010-07-09 15:58:59 +00005208 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
5209 "CreateSymbolicLinkW");
Brian Curtind40e6f72010-07-08 21:39:08 +00005210 if (Py_CreateSymbolicLinkW)
5211 has_CreateSymbolicLinkW = 1;
5212 return has_CreateSymbolicLinkW;
5213}
5214
5215PyDoc_STRVAR(win_symlink__doc__,
5216"symlink(src, dst, target_is_directory=False)\n\n\
5217Create a symbolic link pointing to src named dst.\n\
5218target_is_directory is required if the target is to be interpreted as\n\
5219a directory.\n\
5220This function requires Windows 6.0 or greater, and raises a\n\
5221NotImplementedError otherwise.");
5222
5223static PyObject *
5224win_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
5225{
5226 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
5227 PyObject *src, *dest;
5228 int target_is_directory = 0;
5229 DWORD res;
5230 WIN32_FILE_ATTRIBUTE_DATA src_info;
5231
5232 if (!check_CreateSymbolicLinkW())
5233 {
5234 /* raise NotImplementedError */
5235 return PyErr_Format(PyExc_NotImplementedError,
5236 "CreateSymbolicLinkW not found");
5237 }
5238 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink",
5239 kwlist, &src, &dest, &target_is_directory))
5240 return NULL;
5241 if (!convert_to_unicode(&src)) { return NULL; }
5242 if (!convert_to_unicode(&dest)) {
5243 Py_DECREF(src);
5244 return NULL;
5245 }
5246
5247 /* if src is a directory, ensure target_is_directory==1 */
5248 if(
5249 GetFileAttributesExW(
5250 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
5251 ))
5252 {
5253 target_is_directory = target_is_directory ||
5254 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
5255 }
5256
5257 Py_BEGIN_ALLOW_THREADS
5258 res = Py_CreateSymbolicLinkW(
5259 PyUnicode_AsUnicode(dest),
5260 PyUnicode_AsUnicode(src),
5261 target_is_directory);
5262 Py_END_ALLOW_THREADS
5263 Py_DECREF(src);
5264 Py_DECREF(dest);
5265 if (!res)
5266 {
5267 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
5268 }
5269
5270 Py_INCREF(Py_None);
5271 return Py_None;
5272}
5273#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005274
5275#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00005276#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5277static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005278system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005279{
5280 ULONG value = 0;
5281
5282 Py_BEGIN_ALLOW_THREADS
5283 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5284 Py_END_ALLOW_THREADS
5285
5286 return value;
5287}
5288
5289static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005290posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005291{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005292 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinner8c62be82010-05-06 00:08:46 +00005293 return Py_BuildValue("ddddd",
5294 (double)0 /* t.tms_utime / HZ */,
5295 (double)0 /* t.tms_stime / HZ */,
5296 (double)0 /* t.tms_cutime / HZ */,
5297 (double)0 /* t.tms_cstime / HZ */,
5298 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005299}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005300#else /* not OS2 */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00005301#define NEED_TICKS_PER_SECOND
5302static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00005303static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005304posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005305{
Victor Stinner8c62be82010-05-06 00:08:46 +00005306 struct tms t;
5307 clock_t c;
5308 errno = 0;
5309 c = times(&t);
5310 if (c == (clock_t) -1)
5311 return posix_error();
5312 return Py_BuildValue("ddddd",
5313 (double)t.tms_utime / ticks_per_second,
5314 (double)t.tms_stime / ticks_per_second,
5315 (double)t.tms_cutime / ticks_per_second,
5316 (double)t.tms_cstime / ticks_per_second,
5317 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005318}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005319#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005320#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005321
5322
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005323#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005324#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005325static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005326posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005327{
Victor Stinner8c62be82010-05-06 00:08:46 +00005328 FILETIME create, exit, kernel, user;
5329 HANDLE hProc;
5330 hProc = GetCurrentProcess();
5331 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5332 /* The fields of a FILETIME structure are the hi and lo part
5333 of a 64-bit value expressed in 100 nanosecond units.
5334 1e7 is one second in such units; 1e-7 the inverse.
5335 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5336 */
5337 return Py_BuildValue(
5338 "ddddd",
5339 (double)(user.dwHighDateTime*429.4967296 +
5340 user.dwLowDateTime*1e-7),
5341 (double)(kernel.dwHighDateTime*429.4967296 +
5342 kernel.dwLowDateTime*1e-7),
5343 (double)0,
5344 (double)0,
5345 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005346}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005347#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005348
5349#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005350PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005351"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005352Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005353#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005354
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005355
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005356#ifdef HAVE_GETSID
5357PyDoc_STRVAR(posix_getsid__doc__,
5358"getsid(pid) -> sid\n\n\
5359Call the system call getsid().");
5360
5361static PyObject *
5362posix_getsid(PyObject *self, PyObject *args)
5363{
Victor Stinner8c62be82010-05-06 00:08:46 +00005364 pid_t pid;
5365 int sid;
5366 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid))
5367 return NULL;
5368 sid = getsid(pid);
5369 if (sid < 0)
5370 return posix_error();
5371 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005372}
5373#endif /* HAVE_GETSID */
5374
5375
Guido van Rossumb6775db1994-08-01 11:34:53 +00005376#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005377PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005378"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005379Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005380
Barry Warsaw53699e91996-12-10 23:23:01 +00005381static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005382posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005383{
Victor Stinner8c62be82010-05-06 00:08:46 +00005384 if (setsid() < 0)
5385 return posix_error();
5386 Py_INCREF(Py_None);
5387 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005388}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005389#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005390
Guido van Rossumb6775db1994-08-01 11:34:53 +00005391#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005392PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005393"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005394Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005395
Barry Warsaw53699e91996-12-10 23:23:01 +00005396static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005397posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005398{
Victor Stinner8c62be82010-05-06 00:08:46 +00005399 pid_t pid;
5400 int pgrp;
5401 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp))
5402 return NULL;
5403 if (setpgid(pid, pgrp) < 0)
5404 return posix_error();
5405 Py_INCREF(Py_None);
5406 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005407}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005408#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005409
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005410
Guido van Rossumb6775db1994-08-01 11:34:53 +00005411#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005412PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005413"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005414Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005415
Barry Warsaw53699e91996-12-10 23:23:01 +00005416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005417posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005418{
Victor Stinner8c62be82010-05-06 00:08:46 +00005419 int fd;
5420 pid_t pgid;
5421 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5422 return NULL;
5423 pgid = tcgetpgrp(fd);
5424 if (pgid < 0)
5425 return posix_error();
5426 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005427}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005428#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005429
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005430
Guido van Rossumb6775db1994-08-01 11:34:53 +00005431#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005432PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005433"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005434Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005435
Barry Warsaw53699e91996-12-10 23:23:01 +00005436static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005437posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005438{
Victor Stinner8c62be82010-05-06 00:08:46 +00005439 int fd;
5440 pid_t pgid;
5441 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid))
5442 return NULL;
5443 if (tcsetpgrp(fd, pgid) < 0)
5444 return posix_error();
5445 Py_INCREF(Py_None);
5446 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005447}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005448#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005449
Guido van Rossum687dd131993-05-17 08:34:16 +00005450/* Functions acting on file descriptors */
5451
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005452PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005453"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005454Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005455
Barry Warsaw53699e91996-12-10 23:23:01 +00005456static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005457posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005458{
Victor Stinner8c62be82010-05-06 00:08:46 +00005459 PyObject *ofile;
5460 char *file;
5461 int flag;
5462 int mode = 0777;
5463 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005464
5465#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005466 PyUnicodeObject *po;
5467 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5468 Py_BEGIN_ALLOW_THREADS
5469 /* PyUnicode_AS_UNICODE OK without thread
5470 lock as it is a simple dereference. */
5471 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5472 Py_END_ALLOW_THREADS
5473 if (fd < 0)
5474 return posix_error();
5475 return PyLong_FromLong((long)fd);
5476 }
5477 /* Drop the argument parsing error as narrow strings
5478 are also valid. */
5479 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005480#endif
5481
Victor Stinner8c62be82010-05-06 00:08:46 +00005482 if (!PyArg_ParseTuple(args, "O&i|i",
5483 PyUnicode_FSConverter, &ofile,
5484 &flag, &mode))
5485 return NULL;
5486 file = PyBytes_AsString(ofile);
5487 Py_BEGIN_ALLOW_THREADS
5488 fd = open(file, flag, mode);
5489 Py_END_ALLOW_THREADS
5490 if (fd < 0)
5491 return posix_error_with_allocated_filename(ofile);
5492 Py_DECREF(ofile);
5493 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005494}
5495
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005496
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005497PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005498"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005499Close a file descriptor (for low level IO).");
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_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005503{
Victor Stinner8c62be82010-05-06 00:08:46 +00005504 int fd, res;
5505 if (!PyArg_ParseTuple(args, "i:close", &fd))
5506 return NULL;
5507 if (!_PyVerify_fd(fd))
5508 return posix_error();
5509 Py_BEGIN_ALLOW_THREADS
5510 res = close(fd);
5511 Py_END_ALLOW_THREADS
5512 if (res < 0)
5513 return posix_error();
5514 Py_INCREF(Py_None);
5515 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005516}
5517
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005518
Victor Stinner8c62be82010-05-06 00:08:46 +00005519PyDoc_STRVAR(posix_closerange__doc__,
Christian Heimesfdab48e2008-01-20 09:06:41 +00005520"closerange(fd_low, fd_high)\n\n\
5521Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
5522
5523static PyObject *
5524posix_closerange(PyObject *self, PyObject *args)
5525{
Victor Stinner8c62be82010-05-06 00:08:46 +00005526 int fd_from, fd_to, i;
5527 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
5528 return NULL;
5529 Py_BEGIN_ALLOW_THREADS
5530 for (i = fd_from; i < fd_to; i++)
5531 if (_PyVerify_fd(i))
5532 close(i);
5533 Py_END_ALLOW_THREADS
5534 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00005535}
5536
5537
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005538PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005539"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005540Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005541
Barry Warsaw53699e91996-12-10 23:23:01 +00005542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005543posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005544{
Victor Stinner8c62be82010-05-06 00:08:46 +00005545 int fd;
5546 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5547 return NULL;
5548 if (!_PyVerify_fd(fd))
5549 return posix_error();
5550 Py_BEGIN_ALLOW_THREADS
5551 fd = dup(fd);
5552 Py_END_ALLOW_THREADS
5553 if (fd < 0)
5554 return posix_error();
5555 return PyLong_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005556}
5557
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005558
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005559PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005560"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005561Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005562
Barry Warsaw53699e91996-12-10 23:23:01 +00005563static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005564posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005565{
Victor Stinner8c62be82010-05-06 00:08:46 +00005566 int fd, fd2, res;
5567 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5568 return NULL;
5569 if (!_PyVerify_fd_dup2(fd, fd2))
5570 return posix_error();
5571 Py_BEGIN_ALLOW_THREADS
5572 res = dup2(fd, fd2);
5573 Py_END_ALLOW_THREADS
5574 if (res < 0)
5575 return posix_error();
5576 Py_INCREF(Py_None);
5577 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005578}
5579
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005580
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005581PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005582"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005583Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005584
Barry Warsaw53699e91996-12-10 23:23:01 +00005585static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005586posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005587{
Victor Stinner8c62be82010-05-06 00:08:46 +00005588 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005589#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005590 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005591#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005592 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005593#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005594 PyObject *posobj;
5595 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5596 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005597#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00005598 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5599 switch (how) {
5600 case 0: how = SEEK_SET; break;
5601 case 1: how = SEEK_CUR; break;
5602 case 2: how = SEEK_END; break;
5603 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005604#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005605
5606#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005607 pos = PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005608#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005609 pos = PyLong_Check(posobj) ?
5610 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005611#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005612 if (PyErr_Occurred())
5613 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005614
Victor Stinner8c62be82010-05-06 00:08:46 +00005615 if (!_PyVerify_fd(fd))
5616 return posix_error();
5617 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005618#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005619 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005620#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005621 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005622#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005623 Py_END_ALLOW_THREADS
5624 if (res < 0)
5625 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005626
5627#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005628 return PyLong_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005629#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005630 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005631#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005632}
5633
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005634
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005635PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005636"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005637Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005638
Barry Warsaw53699e91996-12-10 23:23:01 +00005639static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005640posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005641{
Victor Stinner8c62be82010-05-06 00:08:46 +00005642 int fd, size;
5643 Py_ssize_t n;
5644 PyObject *buffer;
5645 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5646 return NULL;
5647 if (size < 0) {
5648 errno = EINVAL;
5649 return posix_error();
5650 }
5651 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5652 if (buffer == NULL)
5653 return NULL;
5654 if (!_PyVerify_fd(fd))
5655 return posix_error();
5656 Py_BEGIN_ALLOW_THREADS
5657 n = read(fd, PyBytes_AS_STRING(buffer), size);
5658 Py_END_ALLOW_THREADS
5659 if (n < 0) {
5660 Py_DECREF(buffer);
5661 return posix_error();
5662 }
5663 if (n != size)
5664 _PyBytes_Resize(&buffer, n);
5665 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00005666}
5667
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005668
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005669PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005670"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005671Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005672
Barry Warsaw53699e91996-12-10 23:23:01 +00005673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005674posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005675{
Victor Stinner8c62be82010-05-06 00:08:46 +00005676 Py_buffer pbuf;
5677 int fd;
5678 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005679
Victor Stinner8c62be82010-05-06 00:08:46 +00005680 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5681 return NULL;
5682 if (!_PyVerify_fd(fd))
5683 return posix_error();
5684 Py_BEGIN_ALLOW_THREADS
5685 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5686 Py_END_ALLOW_THREADS
5687 PyBuffer_Release(&pbuf);
5688 if (size < 0)
5689 return posix_error();
5690 return PyLong_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005691}
5692
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005693
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005694PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005695"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005696Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005697
Barry Warsaw53699e91996-12-10 23:23:01 +00005698static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005699posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005700{
Victor Stinner8c62be82010-05-06 00:08:46 +00005701 int fd;
5702 STRUCT_STAT st;
5703 int res;
5704 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5705 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005706#ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00005707 /* on OpenVMS we must ensure that all bytes are written to the file */
5708 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005709#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005710 if (!_PyVerify_fd(fd))
5711 return posix_error();
5712 Py_BEGIN_ALLOW_THREADS
5713 res = FSTAT(fd, &st);
5714 Py_END_ALLOW_THREADS
5715 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00005716#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005717 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00005718#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005719 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005720#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005721 }
Tim Peters5aa91602002-01-30 05:46:57 +00005722
Victor Stinner8c62be82010-05-06 00:08:46 +00005723 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005724}
5725
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005726PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005727"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005728Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005729connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005730
5731static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005732posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005733{
Victor Stinner8c62be82010-05-06 00:08:46 +00005734 int fd;
5735 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5736 return NULL;
5737 if (!_PyVerify_fd(fd))
5738 return PyBool_FromLong(0);
5739 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005740}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005741
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005742#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005743PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005744"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005745Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005746
Barry Warsaw53699e91996-12-10 23:23:01 +00005747static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005748posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005749{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005750#if defined(PYOS_OS2)
5751 HFILE read, write;
5752 APIRET rc;
5753
Victor Stinner8c62be82010-05-06 00:08:46 +00005754 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005755 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinner8c62be82010-05-06 00:08:46 +00005756 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005757 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005758 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005759
5760 return Py_BuildValue("(ii)", read, write);
5761#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005762#if !defined(MS_WINDOWS)
Victor Stinner8c62be82010-05-06 00:08:46 +00005763 int fds[2];
5764 int res;
5765 Py_BEGIN_ALLOW_THREADS
5766 res = pipe(fds);
5767 Py_END_ALLOW_THREADS
5768 if (res != 0)
5769 return posix_error();
5770 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005771#else /* MS_WINDOWS */
Victor Stinner8c62be82010-05-06 00:08:46 +00005772 HANDLE read, write;
5773 int read_fd, write_fd;
5774 BOOL ok;
5775 Py_BEGIN_ALLOW_THREADS
5776 ok = CreatePipe(&read, &write, NULL, 0);
5777 Py_END_ALLOW_THREADS
5778 if (!ok)
5779 return win32_error("CreatePipe", NULL);
5780 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5781 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5782 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005783#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005784#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005785}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005786#endif /* HAVE_PIPE */
5787
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005788
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005789#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005790PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005791"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005792Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005793
Barry Warsaw53699e91996-12-10 23:23:01 +00005794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005795posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005796{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005797 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005798 char *filename;
5799 int mode = 0666;
5800 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005801 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath,
5802 &mode))
Victor Stinner8c62be82010-05-06 00:08:46 +00005803 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005804 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005805 Py_BEGIN_ALLOW_THREADS
5806 res = mkfifo(filename, mode);
5807 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005808 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005809 if (res < 0)
5810 return posix_error();
5811 Py_INCREF(Py_None);
5812 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005813}
5814#endif
5815
5816
Neal Norwitz11690112002-07-30 01:08:28 +00005817#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005818PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005819"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005820Create a filesystem node (file, device special file or named pipe)\n\
5821named filename. mode specifies both the permissions to use and the\n\
5822type of node to be created, being combined (bitwise OR) with one of\n\
5823S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005824device defines the newly created device special file (probably using\n\
5825os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005826
5827
5828static PyObject *
5829posix_mknod(PyObject *self, PyObject *args)
5830{
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005831 PyObject *opath;
Victor Stinner8c62be82010-05-06 00:08:46 +00005832 char *filename;
5833 int mode = 0600;
5834 int device = 0;
5835 int res;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005836 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath,
5837 &mode, &device))
Victor Stinner8c62be82010-05-06 00:08:46 +00005838 return NULL;
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005839 filename = PyBytes_AS_STRING(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005840 Py_BEGIN_ALLOW_THREADS
5841 res = mknod(filename, mode, device);
5842 Py_END_ALLOW_THREADS
Benjamin Petersond4efbf92010-08-11 19:20:42 +00005843 Py_DECREF(opath);
Victor Stinner8c62be82010-05-06 00:08:46 +00005844 if (res < 0)
5845 return posix_error();
5846 Py_INCREF(Py_None);
5847 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005848}
5849#endif
5850
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005851#ifdef HAVE_DEVICE_MACROS
5852PyDoc_STRVAR(posix_major__doc__,
5853"major(device) -> major number\n\
5854Extracts a device major number from a raw device number.");
5855
5856static PyObject *
5857posix_major(PyObject *self, PyObject *args)
5858{
Victor Stinner8c62be82010-05-06 00:08:46 +00005859 int device;
5860 if (!PyArg_ParseTuple(args, "i:major", &device))
5861 return NULL;
5862 return PyLong_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005863}
5864
5865PyDoc_STRVAR(posix_minor__doc__,
5866"minor(device) -> minor number\n\
5867Extracts a device minor number from a raw device number.");
5868
5869static PyObject *
5870posix_minor(PyObject *self, PyObject *args)
5871{
Victor Stinner8c62be82010-05-06 00:08:46 +00005872 int device;
5873 if (!PyArg_ParseTuple(args, "i:minor", &device))
5874 return NULL;
5875 return PyLong_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005876}
5877
5878PyDoc_STRVAR(posix_makedev__doc__,
5879"makedev(major, minor) -> device number\n\
5880Composes a raw device number from the major and minor device numbers.");
5881
5882static PyObject *
5883posix_makedev(PyObject *self, PyObject *args)
5884{
Victor Stinner8c62be82010-05-06 00:08:46 +00005885 int major, minor;
5886 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5887 return NULL;
5888 return PyLong_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005889}
5890#endif /* device macros */
5891
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005892
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005893#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005894PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005895"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005896Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005897
Barry Warsaw53699e91996-12-10 23:23:01 +00005898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005899posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005900{
Victor Stinner8c62be82010-05-06 00:08:46 +00005901 int fd;
5902 off_t length;
5903 int res;
5904 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005905
Victor Stinner8c62be82010-05-06 00:08:46 +00005906 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5907 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005908
5909#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00005910 length = PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005911#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 length = PyLong_Check(lenobj) ?
5913 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005914#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005915 if (PyErr_Occurred())
5916 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005917
Victor Stinner8c62be82010-05-06 00:08:46 +00005918 Py_BEGIN_ALLOW_THREADS
5919 res = ftruncate(fd, length);
5920 Py_END_ALLOW_THREADS
5921 if (res < 0)
5922 return posix_error();
5923 Py_INCREF(Py_None);
5924 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005925}
5926#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005927
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005928#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005929PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005930"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005931Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005932
Fred Drake762e2061999-08-26 17:23:54 +00005933/* Save putenv() parameters as values here, so we can collect them when they
5934 * get re-set with another call for the same key. */
5935static PyObject *posix_putenv_garbage;
5936
Tim Peters5aa91602002-01-30 05:46:57 +00005937static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005938posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005939{
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005940#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005941 wchar_t *s1, *s2;
5942 wchar_t *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005943#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005944 PyObject *os1, *os2;
5945 char *s1, *s2;
5946 char *newenv;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005947#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005948 PyObject *newstr = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005949 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005950
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005951#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005952 if (!PyArg_ParseTuple(args,
5953 "uu:putenv",
5954 &s1, &s2))
5955 return NULL;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005956#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005957 if (!PyArg_ParseTuple(args,
5958 "O&O&:putenv",
5959 PyUnicode_FSConverter, &os1,
5960 PyUnicode_FSConverter, &os2))
5961 return NULL;
5962 s1 = PyBytes_AsString(os1);
5963 s2 = PyBytes_AsString(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00005964#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005965
5966#if defined(PYOS_OS2)
5967 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5968 APIRET rc;
5969
Guido van Rossumd48f2521997-12-05 22:19:34 +00005970 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005971 if (rc != NO_ERROR) {
5972 os2_error(rc);
5973 goto error;
5974 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005975
5976 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5977 APIRET rc;
5978
Guido van Rossumd48f2521997-12-05 22:19:34 +00005979 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
Victor Stinner84ae1182010-05-06 22:05:07 +00005980 if (rc != NO_ERROR) {
5981 os2_error(rc);
5982 goto error;
5983 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005984 } else {
5985#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005986 /* XXX This can leak memory -- not easy to fix :-( */
5987 /* len includes space for a trailing \0; the size arg to
5988 PyBytes_FromStringAndSize does not count that */
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005989#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00005990 len = wcslen(s1) + wcslen(s2) + 2;
5991 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005992#else
Victor Stinner84ae1182010-05-06 22:05:07 +00005993 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2;
Victor Stinner8c62be82010-05-06 00:08:46 +00005994 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
Thomas Hellerf78f12a2007-11-08 19:33:05 +00005995#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00005996 if (newstr == NULL) {
5997 PyErr_NoMemory();
5998 goto error;
5999 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006000#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006001 newenv = PyUnicode_AsUnicode(newstr);
6002 _snwprintf(newenv, len, L"%s=%s", s1, s2);
6003 if (_wputenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006004 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00006005 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006006 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006007#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006008 newenv = PyBytes_AS_STRING(newstr);
6009 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6010 if (putenv(newenv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006011 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00006012 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006013 }
Thomas Hellerf78f12a2007-11-08 19:33:05 +00006014#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006015
Victor Stinner8c62be82010-05-06 00:08:46 +00006016 /* Install the first arg and newstr in posix_putenv_garbage;
6017 * this will cause previous value to be collected. This has to
6018 * happen after the real putenv() call because the old value
6019 * was still accessible until then. */
6020 if (PyDict_SetItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006021#ifdef MS_WINDOWS
6022 PyTuple_GET_ITEM(args, 0),
6023#else
6024 os1,
6025#endif
6026 newstr)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006027 /* really not much we can do; just leak */
6028 PyErr_Clear();
6029 }
6030 else {
6031 Py_DECREF(newstr);
6032 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006033
6034#if defined(PYOS_OS2)
6035 }
6036#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006037
Martin v. Löwis011e8422009-05-05 04:43:17 +00006038#ifndef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006039 Py_DECREF(os1);
6040 Py_DECREF(os2);
Martin v. Löwis011e8422009-05-05 04:43:17 +00006041#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00006042 Py_RETURN_NONE;
6043
6044error:
6045#ifndef MS_WINDOWS
6046 Py_DECREF(os1);
6047 Py_DECREF(os2);
6048#endif
6049 Py_XDECREF(newstr);
6050 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006051}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006052#endif /* putenv */
6053
Guido van Rossumc524d952001-10-19 01:31:59 +00006054#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006055PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006056"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006057Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006058
6059static PyObject *
6060posix_unsetenv(PyObject *self, PyObject *args)
6061{
Victor Stinner84ae1182010-05-06 22:05:07 +00006062#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00006063 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006064
Victor Stinner8c62be82010-05-06 00:08:46 +00006065 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6066 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00006067#else
6068 PyObject *os1;
6069 char *s1;
6070
6071 if (!PyArg_ParseTuple(args, "O&:unsetenv",
6072 PyUnicode_FSConverter, &os1))
6073 return NULL;
6074 s1 = PyBytes_AsString(os1);
6075#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006076
Victor Stinner8c62be82010-05-06 00:08:46 +00006077 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006078
Victor Stinner8c62be82010-05-06 00:08:46 +00006079 /* Remove the key from posix_putenv_garbage;
6080 * this will cause it to be collected. This has to
6081 * happen after the real unsetenv() call because the
6082 * old value was still accessible until then.
6083 */
6084 if (PyDict_DelItem(posix_putenv_garbage,
Victor Stinner84ae1182010-05-06 22:05:07 +00006085#ifdef MS_WINDOWS
6086 PyTuple_GET_ITEM(args, 0)
6087#else
6088 os1
6089#endif
6090 )) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006091 /* really not much we can do; just leak */
6092 PyErr_Clear();
6093 }
Guido van Rossumc524d952001-10-19 01:31:59 +00006094
Victor Stinner84ae1182010-05-06 22:05:07 +00006095#ifndef MS_WINDOWS
6096 Py_DECREF(os1);
6097#endif
6098 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00006099}
6100#endif /* unsetenv */
6101
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006102PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006103"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006104Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006105
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006106static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006107posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006108{
Victor Stinner8c62be82010-05-06 00:08:46 +00006109 int code;
6110 char *message;
6111 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6112 return NULL;
6113 message = strerror(code);
6114 if (message == NULL) {
6115 PyErr_SetString(PyExc_ValueError,
6116 "strerror() argument out of range");
6117 return NULL;
6118 }
6119 return PyUnicode_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006120}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006121
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006122
Guido van Rossumc9641791998-08-04 15:26:23 +00006123#ifdef HAVE_SYS_WAIT_H
6124
Fred Drake106c1a02002-04-23 15:58:02 +00006125#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006126PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006127"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006128Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006129
6130static PyObject *
6131posix_WCOREDUMP(PyObject *self, PyObject *args)
6132{
Victor Stinner8c62be82010-05-06 00:08:46 +00006133 WAIT_TYPE status;
6134 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006135
Victor Stinner8c62be82010-05-06 00:08:46 +00006136 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6137 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006138
Victor Stinner8c62be82010-05-06 00:08:46 +00006139 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006140}
6141#endif /* WCOREDUMP */
6142
6143#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006144PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006145"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006146Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006147job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006148
6149static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006150posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006151{
Victor Stinner8c62be82010-05-06 00:08:46 +00006152 WAIT_TYPE status;
6153 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006154
Victor Stinner8c62be82010-05-06 00:08:46 +00006155 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6156 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006157
Victor Stinner8c62be82010-05-06 00:08:46 +00006158 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006159}
6160#endif /* WIFCONTINUED */
6161
Guido van Rossumc9641791998-08-04 15:26:23 +00006162#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006163PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006164"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006165Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006166
6167static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006168posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006169{
Victor Stinner8c62be82010-05-06 00:08:46 +00006170 WAIT_TYPE status;
6171 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006172
Victor Stinner8c62be82010-05-06 00:08:46 +00006173 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6174 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006175
Victor Stinner8c62be82010-05-06 00:08:46 +00006176 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006177}
6178#endif /* WIFSTOPPED */
6179
6180#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006181PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006182"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006183Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006184
6185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006186posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006187{
Victor Stinner8c62be82010-05-06 00:08:46 +00006188 WAIT_TYPE status;
6189 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006190
Victor Stinner8c62be82010-05-06 00:08:46 +00006191 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6192 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006193
Victor Stinner8c62be82010-05-06 00:08:46 +00006194 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006195}
6196#endif /* WIFSIGNALED */
6197
6198#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006199PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006200"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006201Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006202system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006203
6204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006205posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006206{
Victor Stinner8c62be82010-05-06 00:08:46 +00006207 WAIT_TYPE status;
6208 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006209
Victor Stinner8c62be82010-05-06 00:08:46 +00006210 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6211 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006212
Victor Stinner8c62be82010-05-06 00:08:46 +00006213 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006214}
6215#endif /* WIFEXITED */
6216
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006217#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006218PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006219"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006220Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006221
6222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006223posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006224{
Victor Stinner8c62be82010-05-06 00:08:46 +00006225 WAIT_TYPE status;
6226 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006227
Victor Stinner8c62be82010-05-06 00:08:46 +00006228 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6229 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006230
Victor Stinner8c62be82010-05-06 00:08:46 +00006231 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006232}
6233#endif /* WEXITSTATUS */
6234
6235#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006236PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006237"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006238Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006239value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006240
6241static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006242posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006243{
Victor Stinner8c62be82010-05-06 00:08:46 +00006244 WAIT_TYPE status;
6245 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006246
Victor Stinner8c62be82010-05-06 00:08:46 +00006247 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6248 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006249
Victor Stinner8c62be82010-05-06 00:08:46 +00006250 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006251}
6252#endif /* WTERMSIG */
6253
6254#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006255PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006256"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006257Return the signal that stopped the process that provided\n\
6258the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006259
6260static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006261posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006262{
Victor Stinner8c62be82010-05-06 00:08:46 +00006263 WAIT_TYPE status;
6264 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006265
Victor Stinner8c62be82010-05-06 00:08:46 +00006266 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6267 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006268
Victor Stinner8c62be82010-05-06 00:08:46 +00006269 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006270}
6271#endif /* WSTOPSIG */
6272
6273#endif /* HAVE_SYS_WAIT_H */
6274
6275
Thomas Wouters477c8d52006-05-27 19:21:47 +00006276#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006277#ifdef _SCO_DS
6278/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6279 needed definitions in sys/statvfs.h */
6280#define _SVID3
6281#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006282#include <sys/statvfs.h>
6283
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006284static PyObject*
6285_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006286 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6287 if (v == NULL)
6288 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006289
6290#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00006291 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6292 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6293 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
6294 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
6295 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
6296 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
6297 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
6298 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
6299 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6300 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006301#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
6303 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
6304 PyStructSequence_SET_ITEM(v, 2,
6305 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6306 PyStructSequence_SET_ITEM(v, 3,
6307 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6308 PyStructSequence_SET_ITEM(v, 4,
6309 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6310 PyStructSequence_SET_ITEM(v, 5,
6311 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6312 PyStructSequence_SET_ITEM(v, 6,
6313 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6314 PyStructSequence_SET_ITEM(v, 7,
6315 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6316 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
6317 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006318#endif
6319
Victor Stinner8c62be82010-05-06 00:08:46 +00006320 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006321}
6322
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006323PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006324"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006325Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006326
6327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006328posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006329{
Victor Stinner8c62be82010-05-06 00:08:46 +00006330 int fd, res;
6331 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006332
Victor Stinner8c62be82010-05-06 00:08:46 +00006333 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6334 return NULL;
6335 Py_BEGIN_ALLOW_THREADS
6336 res = fstatvfs(fd, &st);
6337 Py_END_ALLOW_THREADS
6338 if (res != 0)
6339 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006340
Victor Stinner8c62be82010-05-06 00:08:46 +00006341 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006342}
Thomas Wouters477c8d52006-05-27 19:21:47 +00006343#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006344
6345
Thomas Wouters477c8d52006-05-27 19:21:47 +00006346#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006347#include <sys/statvfs.h>
6348
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006349PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006350"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006351Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006352
6353static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006354posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006355{
Victor Stinner8c62be82010-05-06 00:08:46 +00006356 char *path;
6357 int res;
6358 struct statvfs st;
6359 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6360 return NULL;
6361 Py_BEGIN_ALLOW_THREADS
6362 res = statvfs(path, &st);
6363 Py_END_ALLOW_THREADS
6364 if (res != 0)
6365 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006366
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006368}
6369#endif /* HAVE_STATVFS */
6370
Fred Drakec9680921999-12-13 16:37:25 +00006371/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6372 * It maps strings representing configuration variable names to
6373 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006374 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006375 * rarely-used constants. There are three separate tables that use
6376 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006377 *
6378 * This code is always included, even if none of the interfaces that
6379 * need it are included. The #if hackery needed to avoid it would be
6380 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006381 */
6382struct constdef {
6383 char *name;
6384 long value;
6385};
6386
Fred Drake12c6e2d1999-12-14 21:25:03 +00006387static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006388conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00006389 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006390{
Christian Heimes217cfd12007-12-02 14:31:20 +00006391 if (PyLong_Check(arg)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006392 *valuep = PyLong_AS_LONG(arg);
6393 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006394 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00006395 else {
Victor Stinner8c62be82010-05-06 00:08:46 +00006396 /* look up the value in the table using a binary search */
6397 size_t lo = 0;
6398 size_t mid;
6399 size_t hi = tablesize;
6400 int cmp;
6401 const char *confname;
6402 if (!PyUnicode_Check(arg)) {
6403 PyErr_SetString(PyExc_TypeError,
6404 "configuration names must be strings or integers");
Guido van Rossumbce56a62007-05-10 18:04:33 +00006405 return 0;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006406 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 confname = _PyUnicode_AsString(arg);
6408 if (confname == NULL)
6409 return 0;
6410 while (lo < hi) {
6411 mid = (lo + hi) / 2;
6412 cmp = strcmp(confname, table[mid].name);
6413 if (cmp < 0)
6414 hi = mid;
6415 else if (cmp > 0)
6416 lo = mid + 1;
6417 else {
6418 *valuep = table[mid].value;
6419 return 1;
6420 }
6421 }
6422 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6423 return 0;
6424 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00006425}
6426
6427
6428#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6429static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006430#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006431 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006432#endif
6433#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006434 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006435#endif
Fred Drakec9680921999-12-13 16:37:25 +00006436#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006437 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006438#endif
6439#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00006441#endif
6442#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00006443 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00006444#endif
6445#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00006446 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00006447#endif
6448#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006450#endif
6451#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00006453#endif
6454#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00006455 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00006456#endif
6457#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006458 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006459#endif
6460#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006461 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00006462#endif
6463#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006464 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006465#endif
6466#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006467 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00006468#endif
6469#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006470 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006471#endif
6472#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00006473 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00006474#endif
6475#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006476 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006477#endif
6478#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00006479 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00006480#endif
6481};
6482
Fred Drakec9680921999-12-13 16:37:25 +00006483static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006484conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006485{
6486 return conv_confname(arg, valuep, posix_constants_pathconf,
6487 sizeof(posix_constants_pathconf)
6488 / sizeof(struct constdef));
6489}
6490#endif
6491
6492#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006493PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006494"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006495Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006496If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006497
6498static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006499posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006500{
6501 PyObject *result = NULL;
6502 int name, fd;
6503
Fred Drake12c6e2d1999-12-14 21:25:03 +00006504 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6505 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006507
Victor Stinner8c62be82010-05-06 00:08:46 +00006508 errno = 0;
6509 limit = fpathconf(fd, name);
6510 if (limit == -1 && errno != 0)
6511 posix_error();
6512 else
6513 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006514 }
6515 return result;
6516}
6517#endif
6518
6519
6520#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006521PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006522"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006523Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006524If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006525
6526static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006527posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006528{
6529 PyObject *result = NULL;
6530 int name;
6531 char *path;
6532
6533 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6534 conv_path_confname, &name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006535 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00006536
Victor Stinner8c62be82010-05-06 00:08:46 +00006537 errno = 0;
6538 limit = pathconf(path, name);
6539 if (limit == -1 && errno != 0) {
6540 if (errno == EINVAL)
6541 /* could be a path or name problem */
6542 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00006543 else
Victor Stinner8c62be82010-05-06 00:08:46 +00006544 posix_error_with_filename(path);
6545 }
6546 else
6547 result = PyLong_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00006548 }
6549 return result;
6550}
6551#endif
6552
6553#ifdef HAVE_CONFSTR
6554static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006555#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00006556 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00006557#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00006558#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006559 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006560#endif
6561#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006562 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00006563#endif
Fred Draked86ed291999-12-15 15:34:33 +00006564#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006565 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006566#endif
6567#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006568 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006569#endif
6570#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006571 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006572#endif
6573#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006574 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006575#endif
Fred Drakec9680921999-12-13 16:37:25 +00006576#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006577 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006578#endif
6579#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006580 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006581#endif
6582#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006583 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006584#endif
6585#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006586 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006587#endif
6588#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006589 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006590#endif
6591#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006592 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006593#endif
6594#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006595 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006596#endif
6597#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006598 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006599#endif
Fred Draked86ed291999-12-15 15:34:33 +00006600#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00006602#endif
Fred Drakec9680921999-12-13 16:37:25 +00006603#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00006605#endif
Fred Draked86ed291999-12-15 15:34:33 +00006606#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00006608#endif
6609#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00006611#endif
6612#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00006614#endif
6615#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006616 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00006617#endif
Fred Drakec9680921999-12-13 16:37:25 +00006618#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006619 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006620#endif
6621#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006622 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006623#endif
6624#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006625 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006626#endif
6627#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006629#endif
6630#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006631 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006632#endif
6633#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006634 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006635#endif
6636#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006637 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006638#endif
6639#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006640 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006641#endif
6642#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006643 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006644#endif
6645#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006646 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006647#endif
6648#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006650#endif
6651#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006652 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006653#endif
6654#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006655 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006656#endif
6657#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006658 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006659#endif
6660#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00006661 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00006662#endif
6663#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00006664 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00006665#endif
Fred Draked86ed291999-12-15 15:34:33 +00006666#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006667 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006668#endif
6669#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00006670 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00006671#endif
6672#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00006673 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00006674#endif
6675#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006676 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006677#endif
6678#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006679 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006680#endif
6681#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00006682 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00006683#endif
6684#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006685 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00006686#endif
6687#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00006688 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00006689#endif
6690#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00006692#endif
6693#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00006694 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00006695#endif
6696#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00006697 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00006698#endif
6699#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00006700 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00006701#endif
6702#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00006703 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00006704#endif
Fred Drakec9680921999-12-13 16:37:25 +00006705};
6706
6707static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006708conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006709{
6710 return conv_confname(arg, valuep, posix_constants_confstr,
6711 sizeof(posix_constants_confstr)
6712 / sizeof(struct constdef));
6713}
6714
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006715PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006716"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006717Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006718
6719static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006720posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006721{
6722 PyObject *result = NULL;
6723 int name;
Victor Stinnercb043522010-09-10 23:49:04 +00006724 char buffer[255];
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006726
Victor Stinnercb043522010-09-10 23:49:04 +00006727 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
6728 return NULL;
6729
6730 errno = 0;
6731 len = confstr(name, buffer, sizeof(buffer));
6732 if (len == 0) {
6733 if (errno) {
6734 posix_error();
6735 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00006736 }
6737 else {
Victor Stinnercb043522010-09-10 23:49:04 +00006738 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00006739 }
6740 }
Victor Stinnercb043522010-09-10 23:49:04 +00006741
6742 if ((unsigned int)len >= sizeof(buffer)) {
6743 char *buf = PyMem_Malloc(len);
6744 if (buf == NULL)
6745 return PyErr_NoMemory();
6746 confstr(name, buf, len);
6747 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
6748 PyMem_Free(buf);
6749 }
6750 else
6751 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006752 return result;
6753}
6754#endif
6755
6756
6757#ifdef HAVE_SYSCONF
6758static struct constdef posix_constants_sysconf[] = {
6759#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00006761#endif
6762#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00006763 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00006764#endif
6765#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006766 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006767#endif
6768#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006769 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006770#endif
6771#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006772 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006773#endif
6774#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00006775 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00006776#endif
6777#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00006779#endif
6780#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00006782#endif
6783#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00006785#endif
6786#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00006787 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00006788#endif
Fred Draked86ed291999-12-15 15:34:33 +00006789#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006790 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00006791#endif
6792#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00006793 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00006794#endif
Fred Drakec9680921999-12-13 16:37:25 +00006795#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006797#endif
Fred Drakec9680921999-12-13 16:37:25 +00006798#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006800#endif
6801#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006803#endif
6804#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006806#endif
6807#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00006809#endif
6810#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006811 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006812#endif
Fred Draked86ed291999-12-15 15:34:33 +00006813#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006814 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00006815#endif
Fred Drakec9680921999-12-13 16:37:25 +00006816#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00006818#endif
6819#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006821#endif
6822#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006824#endif
6825#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006827#endif
6828#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006829 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006830#endif
Fred Draked86ed291999-12-15 15:34:33 +00006831#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00006832 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00006833#endif
Fred Drakec9680921999-12-13 16:37:25 +00006834#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006835 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006836#endif
6837#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006839#endif
6840#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006842#endif
6843#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006845#endif
6846#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006848#endif
6849#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00006851#endif
6852#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006854#endif
6855#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006856 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006857#endif
6858#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006859 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006860#endif
6861#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006863#endif
6864#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006866#endif
6867#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006869#endif
6870#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006871 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006872#endif
6873#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006875#endif
6876#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006877 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006878#endif
6879#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006880 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006881#endif
6882#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00006883 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00006884#endif
6885#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006886 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006887#endif
6888#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006890#endif
6891#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00006893#endif
6894#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006895 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00006896#endif
6897#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006898 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00006899#endif
6900#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00006902#endif
Fred Draked86ed291999-12-15 15:34:33 +00006903#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00006904 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00006905#endif
Fred Drakec9680921999-12-13 16:37:25 +00006906#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006907 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006908#endif
6909#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00006910 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00006911#endif
6912#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006914#endif
Fred Draked86ed291999-12-15 15:34:33 +00006915#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00006916 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00006917#endif
Fred Drakec9680921999-12-13 16:37:25 +00006918#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00006919 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00006920#endif
Fred Draked86ed291999-12-15 15:34:33 +00006921#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00006922 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00006923#endif
6924#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00006925 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00006926#endif
Fred Drakec9680921999-12-13 16:37:25 +00006927#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006928 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006929#endif
6930#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006931 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006932#endif
6933#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006934 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006935#endif
6936#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00006937 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00006938#endif
Fred Draked86ed291999-12-15 15:34:33 +00006939#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00006940 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00006941#endif
Fred Drakec9680921999-12-13 16:37:25 +00006942#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00006943 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00006944#endif
6945#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00006946 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00006947#endif
6948#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006949 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006950#endif
6951#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00006952 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00006953#endif
6954#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00006955 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00006956#endif
6957#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00006959#endif
6960#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00006961 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00006962#endif
Fred Draked86ed291999-12-15 15:34:33 +00006963#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00006964 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00006965#endif
Fred Drakec9680921999-12-13 16:37:25 +00006966#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006967 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006968#endif
6969#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006970 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006971#endif
Fred Draked86ed291999-12-15 15:34:33 +00006972#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006973 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00006974#endif
Fred Drakec9680921999-12-13 16:37:25 +00006975#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00006977#endif
6978#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006979 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006980#endif
6981#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006982 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006983#endif
6984#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006985 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006986#endif
6987#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006988 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006989#endif
6990#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006991 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006992#endif
6993#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00006994 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00006995#endif
6996#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00006997 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00006998#endif
6999#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007000 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00007001#endif
Fred Draked86ed291999-12-15 15:34:33 +00007002#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007003 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00007004#endif
7005#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00007006 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00007007#endif
Fred Drakec9680921999-12-13 16:37:25 +00007008#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00007009 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00007010#endif
7011#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007012 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007013#endif
7014#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007015 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007016#endif
7017#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007018 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007019#endif
7020#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007021 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007022#endif
7023#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00007024 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007025#endif
7026#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00007027 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00007028#endif
7029#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00007030 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00007031#endif
7032#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007033 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00007034#endif
7035#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00007036 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00007037#endif
7038#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00007039 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00007040#endif
7041#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007042 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00007043#endif
7044#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007045 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00007046#endif
7047#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00007048 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00007049#endif
7050#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00007052#endif
7053#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00007055#endif
7056#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00007057 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00007058#endif
7059#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007060 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007061#endif
7062#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007063 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007064#endif
7065#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00007066 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00007067#endif
7068#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007069 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007070#endif
7071#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007072 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007073#endif
7074#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00007076#endif
7077#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007079#endif
7080#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007081 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007082#endif
7083#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007084 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00007085#endif
7086#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00007087 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00007088#endif
7089#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007090 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007091#endif
7092#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007093 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007094#endif
7095#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00007096 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00007097#endif
7098#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007099 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007100#endif
7101#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007102 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007103#endif
7104#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007105 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007106#endif
7107#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007108 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007109#endif
7110#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007112#endif
Fred Draked86ed291999-12-15 15:34:33 +00007113#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00007114 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00007115#endif
Fred Drakec9680921999-12-13 16:37:25 +00007116#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00007117 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00007118#endif
7119#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007120 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007121#endif
7122#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +00007123 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00007124#endif
7125#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007126 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007127#endif
7128#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00007129 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007130#endif
7131#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007132 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007133#endif
7134#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +00007135 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00007136#endif
7137#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00007138 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007139#endif
7140#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007141 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007142#endif
7143#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007144 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007145#endif
7146#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00007147 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007148#endif
7149#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007150 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00007151#endif
7152#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +00007153 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00007154#endif
7155#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +00007156 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00007157#endif
7158#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +00007159 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00007160#endif
7161#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007162 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007163#endif
7164#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007165 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007166#endif
7167#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +00007168 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00007169#endif
7170#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007171 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007172#endif
7173#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007174 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007175#endif
7176#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007177 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007178#endif
7179#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007180 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007181#endif
7182#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007183 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007184#endif
7185#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007186 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007187#endif
7188#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +00007189 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00007190#endif
7191#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007192 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007193#endif
7194#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00007195 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007196#endif
7197#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007198 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007199#endif
7200#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007201 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007202#endif
7203#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +00007204 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00007205#endif
7206#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007207 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007208#endif
7209#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +00007210 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00007211#endif
7212#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007213 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00007214#endif
7215#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +00007216 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00007217#endif
7218#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +00007219 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00007220#endif
7221#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +00007222 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00007223#endif
7224#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00007225 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00007226#endif
7227#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007228 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00007229#endif
7230#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +00007231 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00007232#endif
7233#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +00007234 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00007235#endif
7236#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007237 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007238#endif
7239#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00007240 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007241#endif
7242#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +00007243 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00007244#endif
7245#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +00007246 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00007247#endif
7248#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +00007249 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00007250#endif
7251};
7252
7253static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007254conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007255{
7256 return conv_confname(arg, valuep, posix_constants_sysconf,
7257 sizeof(posix_constants_sysconf)
7258 / sizeof(struct constdef));
7259}
7260
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007261PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007262"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007263Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007264
7265static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007266posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007267{
7268 PyObject *result = NULL;
7269 int name;
7270
7271 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7272 int value;
7273
7274 errno = 0;
7275 value = sysconf(name);
7276 if (value == -1 && errno != 0)
7277 posix_error();
7278 else
Christian Heimes217cfd12007-12-02 14:31:20 +00007279 result = PyLong_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00007280 }
7281 return result;
7282}
7283#endif
7284
7285
Fred Drakebec628d1999-12-15 18:31:10 +00007286/* This code is used to ensure that the tables of configuration value names
7287 * are in sorted order as required by conv_confname(), and also to build the
7288 * the exported dictionaries that are used to publish information about the
7289 * names available on the host platform.
7290 *
7291 * Sorting the table at runtime ensures that the table is properly ordered
7292 * when used, even for platforms we're not able to test on. It also makes
7293 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007294 */
Fred Drakebec628d1999-12-15 18:31:10 +00007295
7296static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007297cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007298{
7299 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007300 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00007301 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +00007302 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00007303
7304 return strcmp(c1->name, c2->name);
7305}
7306
7307static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007308setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +00007309 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007310{
Fred Drakebec628d1999-12-15 18:31:10 +00007311 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007312 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007313
7314 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7315 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007316 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00007317 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007318
Barry Warsaw3155db32000-04-13 15:20:40 +00007319 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007320 PyObject *o = PyLong_FromLong(table[i].value);
7321 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7322 Py_XDECREF(o);
7323 Py_DECREF(d);
7324 return -1;
7325 }
7326 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007327 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007328 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007329}
7330
Fred Drakebec628d1999-12-15 18:31:10 +00007331/* Return -1 on failure, 0 on success. */
7332static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007333setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007334{
7335#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007336 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007337 sizeof(posix_constants_pathconf)
7338 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007339 "pathconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007340 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007341#endif
7342#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007343 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007344 sizeof(posix_constants_confstr)
7345 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007346 "confstr_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007347 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007348#endif
7349#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007350 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007351 sizeof(posix_constants_sysconf)
7352 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007353 "sysconf_names", module))
Victor Stinner8c62be82010-05-06 00:08:46 +00007354 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007355#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007356 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007357}
Fred Draked86ed291999-12-15 15:34:33 +00007358
7359
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007360PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007361"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007362Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007363in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007364
7365static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007366posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007367{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007368 abort();
7369 /*NOTREACHED*/
7370 Py_FatalError("abort() called from Python code didn't abort!");
7371 return NULL;
7372}
Fred Drakebec628d1999-12-15 18:31:10 +00007373
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007374#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007375PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007376"startfile(filepath [, operation]) - Start a file with its associated\n\
7377application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007378\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007379When \"operation\" is not specified or \"open\", this acts like\n\
7380double-clicking the file in Explorer, or giving the file name as an\n\
7381argument to the DOS \"start\" command: the file is opened with whatever\n\
7382application (if any) its extension is associated.\n\
7383When another \"operation\" is given, it specifies what should be done with\n\
7384the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007385\n\
7386startfile returns as soon as the associated application is launched.\n\
7387There is no option to wait for the application to close, and no way\n\
7388to retrieve the application's exit status.\n\
7389\n\
7390The filepath is relative to the current directory. If you want to use\n\
7391an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007392the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007393
7394static PyObject *
7395win32_startfile(PyObject *self, PyObject *args)
7396{
Victor Stinner8c62be82010-05-06 00:08:46 +00007397 PyObject *ofilepath;
7398 char *filepath;
7399 char *operation = NULL;
7400 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00007401
Victor Stinner8c62be82010-05-06 00:08:46 +00007402 PyObject *unipath, *woperation = NULL;
7403 if (!PyArg_ParseTuple(args, "U|s:startfile",
7404 &unipath, &operation)) {
7405 PyErr_Clear();
7406 goto normal;
7407 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007408
Victor Stinner8c62be82010-05-06 00:08:46 +00007409 if (operation) {
7410 woperation = PyUnicode_DecodeASCII(operation,
7411 strlen(operation), NULL);
7412 if (!woperation) {
7413 PyErr_Clear();
7414 operation = NULL;
7415 goto normal;
7416 }
7417 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00007418
Victor Stinner8c62be82010-05-06 00:08:46 +00007419 Py_BEGIN_ALLOW_THREADS
7420 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7421 PyUnicode_AS_UNICODE(unipath),
7422 NULL, NULL, SW_SHOWNORMAL);
7423 Py_END_ALLOW_THREADS
7424
7425 Py_XDECREF(woperation);
7426 if (rc <= (HINSTANCE)32) {
7427 PyObject *errval = win32_error_unicode("startfile",
7428 PyUnicode_AS_UNICODE(unipath));
7429 return errval;
7430 }
7431 Py_INCREF(Py_None);
7432 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007433
7434normal:
Victor Stinner8c62be82010-05-06 00:08:46 +00007435 if (!PyArg_ParseTuple(args, "O&|s:startfile",
7436 PyUnicode_FSConverter, &ofilepath,
7437 &operation))
7438 return NULL;
7439 filepath = PyBytes_AsString(ofilepath);
7440 Py_BEGIN_ALLOW_THREADS
7441 rc = ShellExecute((HWND)0, operation, filepath,
7442 NULL, NULL, SW_SHOWNORMAL);
7443 Py_END_ALLOW_THREADS
7444 if (rc <= (HINSTANCE)32) {
7445 PyObject *errval = win32_error("startfile", filepath);
7446 Py_DECREF(ofilepath);
7447 return errval;
7448 }
7449 Py_DECREF(ofilepath);
7450 Py_INCREF(Py_None);
7451 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007452}
7453#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007454
Martin v. Löwis438b5342002-12-27 10:16:42 +00007455#ifdef HAVE_GETLOADAVG
7456PyDoc_STRVAR(posix_getloadavg__doc__,
7457"getloadavg() -> (float, float, float)\n\n\
7458Return the number of processes in the system run queue averaged over\n\
7459the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7460was unobtainable");
7461
7462static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007463posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007464{
7465 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007466 if (getloadavg(loadavg, 3)!=3) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007467 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7468 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00007469 } else
Victor Stinner8c62be82010-05-06 00:08:46 +00007470 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00007471}
7472#endif
7473
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007474#ifdef MS_WINDOWS
7475
7476PyDoc_STRVAR(win32_urandom__doc__,
7477"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007478Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007479
7480typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7481 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7482 DWORD dwFlags );
7483typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7484 BYTE *pbBuffer );
7485
7486static CRYPTGENRANDOM pCryptGenRandom = NULL;
Thomas Wouters89d996e2007-09-08 17:39:28 +00007487/* This handle is never explicitly released. Instead, the operating
7488 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007489static HCRYPTPROV hCryptProv = 0;
7490
Tim Peters4ad82172004-08-30 17:02:04 +00007491static PyObject*
7492win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007493{
Victor Stinner8c62be82010-05-06 00:08:46 +00007494 int howMany;
7495 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007496
Victor Stinner8c62be82010-05-06 00:08:46 +00007497 /* Read arguments */
7498 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7499 return NULL;
7500 if (howMany < 0)
7501 return PyErr_Format(PyExc_ValueError,
7502 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007503
Victor Stinner8c62be82010-05-06 00:08:46 +00007504 if (hCryptProv == 0) {
7505 HINSTANCE hAdvAPI32 = NULL;
7506 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007507
Victor Stinner8c62be82010-05-06 00:08:46 +00007508 /* Obtain handle to the DLL containing CryptoAPI
7509 This should not fail */
7510 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7511 if(hAdvAPI32 == NULL)
7512 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007513
Victor Stinner8c62be82010-05-06 00:08:46 +00007514 /* Obtain pointers to the CryptoAPI functions
7515 This will fail on some early versions of Win95 */
7516 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7517 hAdvAPI32,
7518 "CryptAcquireContextA");
7519 if (pCryptAcquireContext == NULL)
7520 return PyErr_Format(PyExc_NotImplementedError,
7521 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007522
Victor Stinner8c62be82010-05-06 00:08:46 +00007523 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7524 hAdvAPI32, "CryptGenRandom");
7525 if (pCryptGenRandom == NULL)
7526 return PyErr_Format(PyExc_NotImplementedError,
7527 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007528
Victor Stinner8c62be82010-05-06 00:08:46 +00007529 /* Acquire context */
7530 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7531 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7532 return win32_error("CryptAcquireContext", NULL);
7533 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007534
Victor Stinner8c62be82010-05-06 00:08:46 +00007535 /* Allocate bytes */
7536 result = PyBytes_FromStringAndSize(NULL, howMany);
7537 if (result != NULL) {
7538 /* Get random data */
7539 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
7540 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7541 PyBytes_AS_STRING(result))) {
7542 Py_DECREF(result);
7543 return win32_error("CryptGenRandom", NULL);
7544 }
7545 }
7546 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007547}
7548#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007549
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007550PyDoc_STRVAR(device_encoding__doc__,
7551"device_encoding(fd) -> str\n\n\
7552Return a string describing the encoding of the device\n\
7553if the output is a terminal; else return None.");
7554
7555static PyObject *
7556device_encoding(PyObject *self, PyObject *args)
7557{
Victor Stinner8c62be82010-05-06 00:08:46 +00007558 int fd;
7559 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
7560 return NULL;
7561 if (!_PyVerify_fd(fd) || !isatty(fd)) {
7562 Py_INCREF(Py_None);
7563 return Py_None;
7564 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007565#if defined(MS_WINDOWS) || defined(MS_WIN64)
Victor Stinner8c62be82010-05-06 00:08:46 +00007566 if (fd == 0) {
7567 char buf[100];
7568 sprintf(buf, "cp%d", GetConsoleCP());
7569 return PyUnicode_FromString(buf);
7570 }
7571 if (fd == 1 || fd == 2) {
7572 char buf[100];
7573 sprintf(buf, "cp%d", GetConsoleOutputCP());
7574 return PyUnicode_FromString(buf);
7575 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007576#elif defined(CODESET)
Victor Stinner8c62be82010-05-06 00:08:46 +00007577 {
7578 char *codeset = nl_langinfo(CODESET);
7579 if (codeset != NULL && codeset[0] != 0)
7580 return PyUnicode_FromString(codeset);
7581 }
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007582#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007583 Py_INCREF(Py_None);
7584 return Py_None;
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +00007585}
7586
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007587#ifdef __VMS
7588/* Use openssl random routine */
7589#include <openssl/rand.h>
7590PyDoc_STRVAR(vms_urandom__doc__,
7591"urandom(n) -> str\n\n\
Neal Norwitz93c56822007-08-26 07:10:06 +00007592Return n random bytes suitable for cryptographic use.");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007593
7594static PyObject*
7595vms_urandom(PyObject *self, PyObject *args)
7596{
Victor Stinner8c62be82010-05-06 00:08:46 +00007597 int howMany;
7598 PyObject* result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007599
Victor Stinner8c62be82010-05-06 00:08:46 +00007600 /* Read arguments */
7601 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7602 return NULL;
7603 if (howMany < 0)
7604 return PyErr_Format(PyExc_ValueError,
7605 "negative argument not allowed");
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007606
Victor Stinner8c62be82010-05-06 00:08:46 +00007607 /* Allocate bytes */
7608 result = PyBytes_FromStringAndSize(NULL, howMany);
7609 if (result != NULL) {
7610 /* Get random data */
7611 if (RAND_pseudo_bytes((unsigned char*)
7612 PyBytes_AS_STRING(result),
7613 howMany) < 0) {
7614 Py_DECREF(result);
7615 return PyErr_Format(PyExc_ValueError,
7616 "RAND_pseudo_bytes");
7617 }
7618 }
7619 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007620}
7621#endif
7622
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007623#ifdef HAVE_SETRESUID
7624PyDoc_STRVAR(posix_setresuid__doc__,
7625"setresuid(ruid, euid, suid)\n\n\
7626Set the current process's real, effective, and saved user ids.");
7627
7628static PyObject*
7629posix_setresuid (PyObject *self, PyObject *args)
7630{
Victor Stinner8c62be82010-05-06 00:08:46 +00007631 /* We assume uid_t is no larger than a long. */
7632 long ruid, euid, suid;
7633 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
7634 return NULL;
7635 if (setresuid(ruid, euid, suid) < 0)
7636 return posix_error();
7637 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007638}
7639#endif
7640
7641#ifdef HAVE_SETRESGID
7642PyDoc_STRVAR(posix_setresgid__doc__,
7643"setresgid(rgid, egid, sgid)\n\n\
7644Set the current process's real, effective, and saved group ids.");
7645
7646static PyObject*
7647posix_setresgid (PyObject *self, PyObject *args)
7648{
Victor Stinner8c62be82010-05-06 00:08:46 +00007649 /* We assume uid_t is no larger than a long. */
7650 long rgid, egid, sgid;
7651 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
7652 return NULL;
7653 if (setresgid(rgid, egid, sgid) < 0)
7654 return posix_error();
7655 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007656}
7657#endif
7658
7659#ifdef HAVE_GETRESUID
7660PyDoc_STRVAR(posix_getresuid__doc__,
7661"getresuid() -> (ruid, euid, suid)\n\n\
7662Get tuple of the current process's real, effective, and saved user ids.");
7663
7664static PyObject*
7665posix_getresuid (PyObject *self, PyObject *noargs)
7666{
Victor Stinner8c62be82010-05-06 00:08:46 +00007667 uid_t ruid, euid, suid;
7668 long l_ruid, l_euid, l_suid;
7669 if (getresuid(&ruid, &euid, &suid) < 0)
7670 return posix_error();
7671 /* Force the values into long's as we don't know the size of uid_t. */
7672 l_ruid = ruid;
7673 l_euid = euid;
7674 l_suid = suid;
7675 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007676}
7677#endif
7678
7679#ifdef HAVE_GETRESGID
7680PyDoc_STRVAR(posix_getresgid__doc__,
7681"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandla9b51d22010-09-05 17:07:12 +00007682Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007683
7684static PyObject*
7685posix_getresgid (PyObject *self, PyObject *noargs)
7686{
Victor Stinner8c62be82010-05-06 00:08:46 +00007687 uid_t rgid, egid, sgid;
7688 long l_rgid, l_egid, l_sgid;
7689 if (getresgid(&rgid, &egid, &sgid) < 0)
7690 return posix_error();
7691 /* Force the values into long's as we don't know the size of uid_t. */
7692 l_rgid = rgid;
7693 l_egid = egid;
7694 l_sgid = sgid;
7695 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00007696}
7697#endif
7698
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007699static PyMethodDef posix_methods[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00007700 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007701#ifdef HAVE_TTYNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007702 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007703#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007704 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007705#ifdef HAVE_CHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007706 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007707#endif /* HAVE_CHFLAGS */
Victor Stinner8c62be82010-05-06 00:08:46 +00007708 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007709#ifdef HAVE_FCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007710 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007711#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007712#ifdef HAVE_CHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007713 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007714#endif /* HAVE_CHOWN */
Christian Heimes4e30a842007-11-30 22:12:06 +00007715#ifdef HAVE_LCHMOD
Victor Stinner8c62be82010-05-06 00:08:46 +00007716 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007717#endif /* HAVE_LCHMOD */
7718#ifdef HAVE_FCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007719 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes4e30a842007-11-30 22:12:06 +00007720#endif /* HAVE_FCHOWN */
Thomas Wouterscf297e42007-02-23 15:07:44 +00007721#ifdef HAVE_LCHFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00007722 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Thomas Wouterscf297e42007-02-23 15:07:44 +00007723#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007724#ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00007725 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007726#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007727#ifdef HAVE_CHROOT
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00007729#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007730#ifdef HAVE_CTERMID
Victor Stinner8c62be82010-05-06 00:08:46 +00007731 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007732#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007733#ifdef HAVE_GETCWD
Victor Stinner8c62be82010-05-06 00:08:46 +00007734 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7735 METH_NOARGS, posix_getcwd__doc__},
7736 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7737 METH_NOARGS, posix_getcwdb__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007738#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007739#ifdef HAVE_LINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007740 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007741#endif /* HAVE_LINK */
Victor Stinner8c62be82010-05-06 00:08:46 +00007742 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7743 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7744 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007745#ifdef HAVE_NICE
Victor Stinner8c62be82010-05-06 00:08:46 +00007746 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007747#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007748#ifdef HAVE_READLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007749 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007750#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007751#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007752 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007753#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +00007754 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7755 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7756 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +00007757 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007758#ifdef HAVE_SYMLINK
Victor Stinner8c62be82010-05-06 00:08:46 +00007759 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007760#endif /* HAVE_SYMLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +00007761#if !defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin74e45612010-07-09 15:58:59 +00007762 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS,
7763 win_symlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +00007764#endif /* !defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007765#ifdef HAVE_SYSTEM
Victor Stinner8c62be82010-05-06 00:08:46 +00007766 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007767#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007768 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007769#ifdef HAVE_UNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007771#endif /* HAVE_UNAME */
Victor Stinner8c62be82010-05-06 00:08:46 +00007772 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7773 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7774 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007775#ifdef HAVE_TIMES
Victor Stinner8c62be82010-05-06 00:08:46 +00007776 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007777#endif /* HAVE_TIMES */
Victor Stinner8c62be82010-05-06 00:08:46 +00007778 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007779#ifdef HAVE_EXECV
Victor Stinner8c62be82010-05-06 00:08:46 +00007780 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7781 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007782#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007783#ifdef HAVE_SPAWNV
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7785 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007786#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00007787 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7788 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007789#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007790#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007791#ifdef HAVE_FORK1
Victor Stinner8c62be82010-05-06 00:08:46 +00007792 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007793#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007794#ifdef HAVE_FORK
Victor Stinner8c62be82010-05-06 00:08:46 +00007795 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007796#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007797#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinner8c62be82010-05-06 00:08:46 +00007798 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007799#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007800#ifdef HAVE_FORKPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007802#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007803#ifdef HAVE_GETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007805#endif /* HAVE_GETEGID */
7806#ifdef HAVE_GETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007807 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007808#endif /* HAVE_GETEUID */
7809#ifdef HAVE_GETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007810 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007811#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007812#ifdef HAVE_GETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007813 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007814#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007815 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007816#ifdef HAVE_GETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007817 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007818#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007819#ifdef HAVE_GETPPID
Victor Stinner8c62be82010-05-06 00:08:46 +00007820 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007821#endif /* HAVE_GETPPID */
7822#ifdef HAVE_GETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007823 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007824#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007825#ifdef HAVE_GETLOGIN
Victor Stinner8c62be82010-05-06 00:08:46 +00007826 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007827#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007828#ifdef HAVE_KILL
Victor Stinner8c62be82010-05-06 00:08:46 +00007829 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007830#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007831#ifdef HAVE_KILLPG
Victor Stinner8c62be82010-05-06 00:08:46 +00007832 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007833#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007834#ifdef HAVE_PLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00007835 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007836#endif /* HAVE_PLOCK */
Thomas Heller8b7a9572007-08-31 06:44:36 +00007837#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007838 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7839 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +00007840#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007841#ifdef HAVE_SETUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007842 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007843#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007844#ifdef HAVE_SETEUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007845 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007846#endif /* HAVE_SETEUID */
7847#ifdef HAVE_SETEGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007848 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007849#endif /* HAVE_SETEGID */
7850#ifdef HAVE_SETREUID
Victor Stinner8c62be82010-05-06 00:08:46 +00007851 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007852#endif /* HAVE_SETREUID */
7853#ifdef HAVE_SETREGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007854 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007855#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007856#ifdef HAVE_SETGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007858#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007859#ifdef HAVE_SETGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007860 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007861#endif /* HAVE_SETGROUPS */
Antoine Pitroub7572f02009-12-02 20:46:48 +00007862#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +00007863 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +00007864#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007865#ifdef HAVE_GETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007866 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00007867#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007868#ifdef HAVE_SETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007869 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007870#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007871#ifdef HAVE_WAIT
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007873#endif /* HAVE_WAIT */
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007874#ifdef HAVE_WAIT3
Victor Stinner8c62be82010-05-06 00:08:46 +00007875 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007876#endif /* HAVE_WAIT3 */
7877#ifdef HAVE_WAIT4
Victor Stinner8c62be82010-05-06 00:08:46 +00007878 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007879#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007880#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinner8c62be82010-05-06 00:08:46 +00007881 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007882#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007883#ifdef HAVE_GETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007884 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007885#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007886#ifdef HAVE_SETSID
Victor Stinner8c62be82010-05-06 00:08:46 +00007887 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007888#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007889#ifdef HAVE_SETPGID
Victor Stinner8c62be82010-05-06 00:08:46 +00007890 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007891#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007892#ifdef HAVE_TCGETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007893 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007894#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007895#ifdef HAVE_TCSETPGRP
Victor Stinner8c62be82010-05-06 00:08:46 +00007896 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007897#endif /* HAVE_TCSETPGRP */
Victor Stinner8c62be82010-05-06 00:08:46 +00007898 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7899 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7900 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7901 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7902 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7903 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7904 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7905 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7906 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7907 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7908 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007909#ifdef HAVE_PIPE
Victor Stinner8c62be82010-05-06 00:08:46 +00007910 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007911#endif
7912#ifdef HAVE_MKFIFO
Victor Stinner8c62be82010-05-06 00:08:46 +00007913 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007914#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007915#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinner8c62be82010-05-06 00:08:46 +00007916 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007917#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007918#ifdef HAVE_DEVICE_MACROS
Victor Stinner8c62be82010-05-06 00:08:46 +00007919 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7920 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7921 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007922#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007923#ifdef HAVE_FTRUNCATE
Victor Stinner8c62be82010-05-06 00:08:46 +00007924 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007925#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007926#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007927 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007928#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007929#ifdef HAVE_UNSETENV
Victor Stinner8c62be82010-05-06 00:08:46 +00007930 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00007931#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007932 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007933#ifdef HAVE_FCHDIR
Victor Stinner8c62be82010-05-06 00:08:46 +00007934 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00007935#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007936#ifdef HAVE_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007937 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007938#endif
7939#ifdef HAVE_FDATASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00007940 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007941#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007942#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007943#ifdef WCOREDUMP
Victor Stinner8c62be82010-05-06 00:08:46 +00007944 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00007945#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007946#ifdef WIFCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00007947 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007948#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007949#ifdef WIFSTOPPED
Victor Stinner8c62be82010-05-06 00:08:46 +00007950 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007951#endif /* WIFSTOPPED */
7952#ifdef WIFSIGNALED
Victor Stinner8c62be82010-05-06 00:08:46 +00007953 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007954#endif /* WIFSIGNALED */
7955#ifdef WIFEXITED
Victor Stinner8c62be82010-05-06 00:08:46 +00007956 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007957#endif /* WIFEXITED */
7958#ifdef WEXITSTATUS
Victor Stinner8c62be82010-05-06 00:08:46 +00007959 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007960#endif /* WEXITSTATUS */
7961#ifdef WTERMSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007962 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007963#endif /* WTERMSIG */
7964#ifdef WSTOPSIG
Victor Stinner8c62be82010-05-06 00:08:46 +00007965 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007966#endif /* WSTOPSIG */
7967#endif /* HAVE_SYS_WAIT_H */
Thomas Wouters477c8d52006-05-27 19:21:47 +00007968#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007969 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007970#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00007971#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinner8c62be82010-05-06 00:08:46 +00007972 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007973#endif
Fred Drakec9680921999-12-13 16:37:25 +00007974#ifdef HAVE_CONFSTR
Victor Stinner8c62be82010-05-06 00:08:46 +00007975 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007976#endif
7977#ifdef HAVE_SYSCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007978 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007979#endif
7980#ifdef HAVE_FPATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007981 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007982#endif
7983#ifdef HAVE_PATHCONF
Victor Stinner8c62be82010-05-06 00:08:46 +00007984 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007985#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00007986 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007987#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtind40e6f72010-07-08 21:39:08 +00007989 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
Brian Curtin62857742010-09-06 17:07:27 +00007990 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00007991#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007992#ifdef HAVE_GETLOADAVG
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007994#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007995 #ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00007996 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007997 #endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007998 #ifdef __VMS
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008000 #endif
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008001#ifdef HAVE_SETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008002 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008003#endif
8004#ifdef HAVE_SETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008005 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008006#endif
8007#ifdef HAVE_GETRESUID
Victor Stinner8c62be82010-05-06 00:08:46 +00008008 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008009#endif
8010#ifdef HAVE_GETRESGID
Victor Stinner8c62be82010-05-06 00:08:46 +00008011 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis7aed61a2009-11-27 14:09:49 +00008012#endif
8013
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008015};
8016
8017
Barry Warsaw4a342091996-12-19 23:50:02 +00008018static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008019ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008020{
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008022}
8023
Guido van Rossumd48f2521997-12-05 22:19:34 +00008024#if defined(PYOS_OS2)
8025/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008026static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008027{
8028 APIRET rc;
8029 ULONG values[QSV_MAX+1];
8030 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008031 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008032
8033 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008034 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008035 Py_END_ALLOW_THREADS
8036
8037 if (rc != NO_ERROR) {
8038 os2_error(rc);
8039 return -1;
8040 }
8041
Fred Drake4d1e64b2002-04-15 19:40:07 +00008042 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8043 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8044 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8045 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8046 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8047 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8048 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008049
8050 switch (values[QSV_VERSION_MINOR]) {
8051 case 0: ver = "2.00"; break;
8052 case 10: ver = "2.10"; break;
8053 case 11: ver = "2.11"; break;
8054 case 30: ver = "3.00"; break;
8055 case 40: ver = "4.00"; break;
8056 case 50: ver = "5.00"; break;
8057 default:
Tim Peters885d4572001-11-28 20:27:42 +00008058 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinner8c62be82010-05-06 00:08:46 +00008059 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00008060 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008061 ver = &tmp[0];
8062 }
8063
8064 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008065 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008066 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008067
8068 /* Add Indicator of Which Drive was Used to Boot the System */
8069 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8070 tmp[1] = ':';
8071 tmp[2] = '\0';
8072
Fred Drake4d1e64b2002-04-15 19:40:07 +00008073 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008074}
8075#endif
8076
Barry Warsaw4a342091996-12-19 23:50:02 +00008077static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008078all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008079{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008080#ifdef F_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008081 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008082#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008083#ifdef R_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008084 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008085#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008086#ifdef W_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008087 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008088#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008089#ifdef X_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008090 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008091#endif
Fred Drakec9680921999-12-13 16:37:25 +00008092#ifdef NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008093 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00008094#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008095#ifdef TMP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00008096 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008097#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008098#ifdef WCONTINUED
Victor Stinner8c62be82010-05-06 00:08:46 +00008099 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008100#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008101#ifdef WNOHANG
Victor Stinner8c62be82010-05-06 00:08:46 +00008102 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008103#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008104#ifdef WUNTRACED
Victor Stinner8c62be82010-05-06 00:08:46 +00008105 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00008106#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008107#ifdef O_RDONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008108 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008109#endif
8110#ifdef O_WRONLY
Victor Stinner8c62be82010-05-06 00:08:46 +00008111 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008112#endif
8113#ifdef O_RDWR
Victor Stinner8c62be82010-05-06 00:08:46 +00008114 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008115#endif
8116#ifdef O_NDELAY
Victor Stinner8c62be82010-05-06 00:08:46 +00008117 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008118#endif
8119#ifdef O_NONBLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008120 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008121#endif
8122#ifdef O_APPEND
Victor Stinner8c62be82010-05-06 00:08:46 +00008123 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008124#endif
8125#ifdef O_DSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008126 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008127#endif
8128#ifdef O_RSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008129 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008130#endif
8131#ifdef O_SYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008132 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008133#endif
8134#ifdef O_NOCTTY
Victor Stinner8c62be82010-05-06 00:08:46 +00008135 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008136#endif
8137#ifdef O_CREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008138 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008139#endif
8140#ifdef O_EXCL
Victor Stinner8c62be82010-05-06 00:08:46 +00008141 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008142#endif
8143#ifdef O_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008144 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00008145#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008146#ifdef O_BINARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008147 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008148#endif
8149#ifdef O_TEXT
Victor Stinner8c62be82010-05-06 00:08:46 +00008150 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00008151#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008152#ifdef O_LARGEFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008153 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008154#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008155#ifdef O_SHLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008156 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008157#endif
8158#ifdef O_EXLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00008159 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00008160#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008161
Tim Peters5aa91602002-01-30 05:46:57 +00008162/* MS Windows */
8163#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +00008164 /* Don't inherit in child processes. */
8165 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008166#endif
8167#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +00008168 /* Optimize for short life (keep in memory). */
8169 /* MS forgot to define this one with a non-underscore form too. */
8170 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008171#endif
8172#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +00008173 /* Automatically delete when last handle is closed. */
8174 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008175#endif
8176#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +00008177 /* Optimize for random access. */
8178 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008179#endif
8180#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00008181 /* Optimize for sequential access. */
8182 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008183#endif
8184
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008185/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008186#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00008187 /* Send a SIGIO signal whenever input or output
8188 becomes available on file descriptor */
8189 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +00008190#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008191#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +00008192 /* Direct disk access. */
8193 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008194#endif
8195#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +00008196 /* Must be a directory. */
8197 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008198#endif
8199#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +00008200 /* Do not follow links. */
8201 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008202#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008203#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +00008204 /* Do not update the access time. */
8205 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +00008206#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008207
Victor Stinner8c62be82010-05-06 00:08:46 +00008208 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008209#ifdef EX_OK
Victor Stinner8c62be82010-05-06 00:08:46 +00008210 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008211#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008212#ifdef EX_USAGE
Victor Stinner8c62be82010-05-06 00:08:46 +00008213 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008214#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008215#ifdef EX_DATAERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008216 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008217#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008218#ifdef EX_NOINPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00008219 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008220#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008221#ifdef EX_NOUSER
Victor Stinner8c62be82010-05-06 00:08:46 +00008222 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008223#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008224#ifdef EX_NOHOST
Victor Stinner8c62be82010-05-06 00:08:46 +00008225 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008226#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008227#ifdef EX_UNAVAILABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00008228 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008229#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008230#ifdef EX_SOFTWARE
Victor Stinner8c62be82010-05-06 00:08:46 +00008231 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008232#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008233#ifdef EX_OSERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008234 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008235#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008236#ifdef EX_OSFILE
Victor Stinner8c62be82010-05-06 00:08:46 +00008237 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008238#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008239#ifdef EX_CANTCREAT
Victor Stinner8c62be82010-05-06 00:08:46 +00008240 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008241#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008242#ifdef EX_IOERR
Victor Stinner8c62be82010-05-06 00:08:46 +00008243 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008244#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008245#ifdef EX_TEMPFAIL
Victor Stinner8c62be82010-05-06 00:08:46 +00008246 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008247#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008248#ifdef EX_PROTOCOL
Victor Stinner8c62be82010-05-06 00:08:46 +00008249 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008250#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008251#ifdef EX_NOPERM
Victor Stinner8c62be82010-05-06 00:08:46 +00008252 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008253#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008254#ifdef EX_CONFIG
Victor Stinner8c62be82010-05-06 00:08:46 +00008255 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008256#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008257#ifdef EX_NOTFOUND
Victor Stinner8c62be82010-05-06 00:08:46 +00008258 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008259#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008260
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008261 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008262#ifdef ST_RDONLY
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008263 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008264#endif /* ST_RDONLY */
8265#ifdef ST_NOSUID
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +00008266 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +00008267#endif /* ST_NOSUID */
8268
Guido van Rossum246bc171999-02-01 23:54:31 +00008269#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008270#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinner8c62be82010-05-06 00:08:46 +00008271 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8272 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8273 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8274 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8275 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8276 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8277 if (ins(d, "P_PM", (long)P_PM)) return -1;
8278 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8279 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8280 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8281 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8282 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8283 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8284 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8285 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8286 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8287 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8288 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8289 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8290 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008291#else
Victor Stinner8c62be82010-05-06 00:08:46 +00008292 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8293 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8294 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8295 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8296 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008297#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008298#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008299
Guido van Rossumd48f2521997-12-05 22:19:34 +00008300#if defined(PYOS_OS2)
Victor Stinner8c62be82010-05-06 00:08:46 +00008301 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008302#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008303 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00008304}
8305
8306
Tim Peters5aa91602002-01-30 05:46:57 +00008307#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008308#define INITFUNC PyInit_nt
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008309#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008310
8311#elif defined(PYOS_OS2)
Martin v. Löwis1a214512008-06-11 05:26:20 +00008312#define INITFUNC PyInit_os2
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008313#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008314
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008315#else
Martin v. Löwis1a214512008-06-11 05:26:20 +00008316#define INITFUNC PyInit_posix
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008317#define MODNAME "posix"
8318#endif
8319
Martin v. Löwis1a214512008-06-11 05:26:20 +00008320static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +00008321 PyModuleDef_HEAD_INIT,
8322 MODNAME,
8323 posix__doc__,
8324 -1,
8325 posix_methods,
8326 NULL,
8327 NULL,
8328 NULL,
8329 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00008330};
8331
8332
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008333PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008334INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008335{
Victor Stinner8c62be82010-05-06 00:08:46 +00008336 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008337
Victor Stinner8c62be82010-05-06 00:08:46 +00008338 m = PyModule_Create(&posixmodule);
8339 if (m == NULL)
8340 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00008341
Victor Stinner8c62be82010-05-06 00:08:46 +00008342 /* Initialize environ dictionary */
8343 v = convertenviron();
8344 Py_XINCREF(v);
8345 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8346 return NULL;
8347 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008348
Victor Stinner8c62be82010-05-06 00:08:46 +00008349 if (all_ins(m))
8350 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +00008351
Victor Stinner8c62be82010-05-06 00:08:46 +00008352 if (setup_confname_tables(m))
8353 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +00008354
Victor Stinner8c62be82010-05-06 00:08:46 +00008355 Py_INCREF(PyExc_OSError);
8356 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008357
Guido van Rossumb3d39562000-01-31 18:41:26 +00008358#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +00008359 if (posix_putenv_garbage == NULL)
8360 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008361#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008362
Victor Stinner8c62be82010-05-06 00:08:46 +00008363 if (!initialized) {
8364 stat_result_desc.name = MODNAME ".stat_result";
8365 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8366 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8367 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8368 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8369 structseq_new = StatResultType.tp_new;
8370 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008371
Victor Stinner8c62be82010-05-06 00:08:46 +00008372 statvfs_result_desc.name = MODNAME ".statvfs_result";
8373 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008374#ifdef NEED_TICKS_PER_SECOND
8375# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +00008376 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008377# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +00008378 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008379# else
Victor Stinner8c62be82010-05-06 00:08:46 +00008380 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +00008381# endif
8382#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008383 }
8384 Py_INCREF((PyObject*) &StatResultType);
8385 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8386 Py_INCREF((PyObject*) &StatVFSResultType);
8387 PyModule_AddObject(m, "statvfs_result",
8388 (PyObject*) &StatVFSResultType);
8389 initialized = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008390
8391#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +00008392 /*
8393 * Step 2 of weak-linking support on Mac OS X.
8394 *
8395 * The code below removes functions that are not available on the
8396 * currently active platform.
8397 *
8398 * This block allow one to use a python binary that was build on
8399 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8400 * OSX 10.4.
8401 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00008402#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008403 if (fstatvfs == NULL) {
8404 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8405 return NULL;
8406 }
8407 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008408#endif /* HAVE_FSTATVFS */
8409
8410#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +00008411 if (statvfs == NULL) {
8412 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8413 return NULL;
8414 }
8415 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008416#endif /* HAVE_STATVFS */
8417
8418# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +00008419 if (lchown == NULL) {
8420 if (PyObject_DelAttrString(m, "lchown") == -1) {
8421 return NULL;
8422 }
8423 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00008424#endif /* HAVE_LCHOWN */
8425
8426
8427#endif /* __APPLE__ */
Victor Stinner8c62be82010-05-06 00:08:46 +00008428 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00008429
Guido van Rossumb6775db1994-08-01 11:34:53 +00008430}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00008431
8432#ifdef __cplusplus
8433}
8434#endif